C#状态机设计模式是一种行为设计模式,用于管理对象基于状态的行为变化。它通过将不同状态封装为独立类,使状态转换逻辑更加清晰和可维护。
**核心概念:**
- 状态接口:定义所有状态共有的操作
- 具体状态类:实现特定状态的行为逻辑
- 上下文类:维护当前状态并委托状态相关操作
**主要优势:**
- 消除复杂条件判断:用多态替代大量的if-else或switch语句
- 开闭原则:易于添加新状态而不影响现有代码
- 状态转换明确:每个状态只允许合法的操作和转换
- 代码组织清晰:相关行为集中在对应的状态类中
**适用场景:**
- 对象行为随状态改变而显著变化
- 状态转换逻辑复杂且频繁修改
- 需要避免大量的条件分支语句
实现方式:
通常通过定义状态接口、实现具体状态类、创建上下文类来管理状态转换,确保状态间的转换符合业务规则。
以下是代码范例:
cs
// 订单状态接口
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演示结束!");
}
}