设计模式之 状态机 C#范例
C#状态机设计模式是一种行为设计模式,用于管理对象基于状态的行为变化。它通过将不同状态封装为独立类,使状态转换逻辑更加清晰和可维护。
核心概念:
- 状态接口:定义所有状态共有的操作
- 具体状态类:实现特定状态的行为逻辑
- 上下文类:维护当前状态并委托状态相关操作
主要优势:
- 消除复杂条件判断:用多态替代大量的if-else或switch语句
- 开闭原则:易于添加新状态而不影响现有代码
- 状态转换明确:每个状态只允许合法的操作和转换
- 代码组织清晰:相关行为集中在对应的状态类中
适用场景:
- 对象行为随状态改变而显著变化
- 状态转换逻辑复杂且频繁修改
- 需要避免大量的条件分支语句
实现方式:
通常通过定义状态接口、实现具体状态类、创建上下文类来管理状态转换,确保状态间的转换符合业务规则。
以下是代码范例:
// 订单状态接口
public interface IOrderState
{void Confirm(Order order);void Cancel(Order order);void Ship(Order order);void Deliver(Order order);void Complete(Order order);
}// 待确认状态
public class PendingState : IOrderState
{public void Confirm(Order order){Console.WriteLine("订单已确认");order.SetState(new ConfirmedState());}public void Cancel(Order order){Console.WriteLine("订单已取消");order.SetState(new CancelledState());}public void Ship(Order order) => Console.WriteLine("待确认订单不能发货");public void Deliver(Order order) => Console.WriteLine("待确认订单不能送达");public void Complete(Order order) => Console.WriteLine("待确认订单不能完成");
}// 已确认状态
public class ConfirmedState : IOrderState
{public void Confirm(Order order) => Console.WriteLine("订单已经是确认状态");public void Cancel(Order order){Console.WriteLine("订单已取消");order.SetState(new CancelledState());}public void Ship(Order order){Console.WriteLine("订单已发货");order.SetState(new ShippedState());}public void Deliver(Order order) => Console.WriteLine("已确认订单不能直接送达");public void Complete(Order order) => Console.WriteLine("已确认订单不能完成");
}// 已发货状态
public class ShippedState : IOrderState
{public void Confirm(Order order) => Console.WriteLine("已发货订单不能重新确认");public void Cancel(Order order) => Console.WriteLine("已发货订单不能取消");public void Ship(Order order) => Console.WriteLine("订单已经是发货状态");public void Deliver(Order order){Console.WriteLine("订单已送达");order.SetState(new DeliveredState());}public void Complete(Order order) => Console.WriteLine("已发货订单不能完成");
}// 已送达状态
public class DeliveredState : IOrderState
{public void Confirm(Order order) => Console.WriteLine("已送达订单不能重新确认");public void Cancel(Order order) => Console.WriteLine("已送达订单不能取消");public void Ship(Order order) => Console.WriteLine("已送达订单不能重新发货");public void Deliver(Order order) => Console.WriteLine("订单已经是送达状态");public void Complete(Order order){Console.WriteLine("订单已完成");order.SetState(new CompletedState());}
}// 已完成状态
public class CompletedState : IOrderState
{public void Confirm(Order order) => Console.WriteLine("已完成订单不能重新确认");public void Cancel(Order order) => Console.WriteLine("已完成订单不能取消");public void Ship(Order order) => Console.WriteLine("已完成订单不能重新发货");public void Deliver(Order order) => Console.WriteLine("已完成订单不能重新送达");public void Complete(Order order) => Console.WriteLine("订单已经是完成状态");
}// 已取消状态
public class CancelledState : IOrderState
{public void Confirm(Order order) => Console.WriteLine("已取消订单不能确认");public void Cancel(Order order) => Console.WriteLine("订单已经是取消状态");public void Ship(Order order) => Console.WriteLine("已取消订单不能发货");public void Deliver(Order order) => Console.WriteLine("已取消订单不能送达");public void Complete(Order order) => Console.WriteLine("已取消订单不能完成");
}
<code_end>
<code_start project_name=csharp_state_pattern filename=Order.cs title=订单类-状态机上下文 entrypoint=false runnable=false project_final_file=false>
// 订单类 - 状态机上下文
public class Order
{private IOrderState _currentState;public string OrderId { get; }public string CustomerName { get; }public decimal TotalAmount { get; }public Order(string orderId, string customerName, decimal totalAmount){OrderId = orderId;CustomerName = customerName;TotalAmount = totalAmount;_currentState = new PendingState();}public void SetState(IOrderState state){_currentState = state;Console.WriteLine($"订单状态已更新: {state.GetType().Name}");}public string GetCurrentState() => _currentState.GetType().Name;// 状态操作方法public void Confirm() => _currentState.Confirm(this);public void Cancel() => _currentState.Cancel(this);public void Ship() => _currentState.Ship(this);public void Deliver() => _currentState.Deliver(this);public void Complete() => _currentState.Complete(this);public void DisplayStatus(){Console.WriteLine($"订单 {OrderId} - 客户: {CustomerName} - 金额: {TotalAmount:C} - 当前状态: {GetCurrentState()}");}
}
<code_end>
<code_start project_name=csharp_state_pattern filename=StateTransition.cs title=状态转换规则管理器 entrypoint=false runnable=false project_final_file=false>
using System.Collections.Generic;// 状态转换规则
public class StateTransition
{public string FromState { get; }public string Action { get; }public StateTransition(string fromState, string action){FromState = fromState;Action = action;}public override bool Equals(object obj){return obj is StateTransition transition &&FromState == transition.FromState &&Action == transition.Action;}public override int GetHashCode(){return System.HashCode.Combine(FromState, Action);}
}// 状态机配置
public class StateMachineConfiguration
{private readonly Dictionary<StateTransition, string> _transitions;public StateMachineConfiguration(){_transitions = new Dictionary<StateTransition, string>{// 从待确认状态可以转换到已确认或已取消{ new StateTransition("PendingState", "Confirm"), "ConfirmedState" },{ new StateTransition("PendingState", "Cancel"), "CancelledState" },// 从已确认状态可以转换到已发货或已取消{ new StateTransition("ConfirmedState", "Ship"), "ShippedState" },{ new StateTransition("ConfirmedState", "Cancel"), "CancelledState" },// 从已发货状态只能转换到已送达{ new StateTransition("ShippedState", "Deliver"), "DeliveredState" },// 从已送达状态只能转换到已完成{ new StateTransition("DeliveredState", "Complete"), "CompletedState" }};}public bool IsValidTransition(string fromState, string action, out string toState){var transition = new StateTransition(fromState, action);return _transitions.TryGetValue(transition, out toState);}public IEnumerable<string> GetAvailableActions(string currentState){var actions = new List<string>();foreach (var transition in _transitions){if (transition.Key.FromState == currentState){actions.Add(transition.Key.Action);}}return actions;}
}
<code_end>
<code_start project_name=csharp_state_pattern filename=Program.cs title=状态机演示程序主入口 entrypoint=true runnable=true project_final_file=true>
using System;class Program
{static void Main(string[] args){Console.WriteLine("=== C# 状态机设计模式演示 ===\n");// 创建订单var order = new Order("ORD001", "张三", 299.99m);order.DisplayStatus();// 演示正常状态流转Console.WriteLine("\n--- 正常状态流转演示 ---");order.Confirm();order.Ship();order.Deliver();order.Complete();order.DisplayStatus();// 演示无效操作Console.WriteLine("\n--- 无效操作演示 ---");order.Confirm(); // 已完成订单不能重新确认// 创建新订单演示取消流程Console.WriteLine("\n--- 取消流程演示 ---");var order2 = new Order("ORD002", "李四", 159.50m);order2.DisplayStatus();order2.Cancel();order2.DisplayStatus();order2.Ship(); // 已取消订单不能发货// 状态机配置演示Console.WriteLine("\n--- 状态机配置演示 ---");var config = new StateMachineConfiguration();var currentState = "PendingState";Console.WriteLine($"当前状态: {currentState}");Console.WriteLine("可用操作: " + string.Join(", ", config.GetAvailableActions(currentState)));// 验证转换规则if (config.IsValidTransition("PendingState", "Confirm", out var toState)){Console.WriteLine($"有效转换: PendingState -> Confirm -> {toState}");}if (!config.IsValidTransition("CompletedState", "Cancel", out _)){Console.WriteLine("无效转换: CompletedState -> Cancel");}Console.WriteLine("\n演示结束!");}
}