状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。
1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
2.操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。 通常,有多个操作包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
两种设计模式都是将一系列逻辑封装在不同的类中,区别是状态模式的逻辑封装类中是根据类的状态不同,而自动选择对应的状态类去处理请求。策略模式允许客户端扩展。两种设计模式很像,只是个人理解不一定对。
上下文:
public class OrderContext { private static readonly ConcurrentDictionary<EOrderState, OrderState> ORDER_STATE_DICT = new System.Collections.Concurrent.ConcurrentDictionary<EOrderState, OrderState>(); internal Order_master OrderMaster = null; public OrderContext(Order_master orderMaster) { OrderMaster = orderMaster; } static OrderContext() { ORDER_STATE_DICT.TryAdd(EOrderState.等待付款, new WaitPayState()); ORDER_STATE_DICT.TryAdd(EOrderState.已付款, new PaiedState()); ORDER_STATE_DICT.TryAdd(EOrderState.已取消, new CancelState()); } public void SetState(Order_master orderMaster, EOrderState state) { OrderState orderState = ORDER_STATE_DICT[state]; orderState.SetState(this); } }
订单状态枚举:
public enum EOrderState { 等待付款 = 1, 已付款 = 2, 已取消 = 3 }
订单类:
public class Order_master { public int OrderID { get; set; } public int State { get; set; } }
订单状态类:(待付款、已支付、已取消)
public abstract class OrderState { public abstract void SetState(OrderContext context); } public class WaitPayState : OrderState { public override void SetState(OrderContext context) { if (context.OrderMaster.State == 0) { context.OrderMaster.State = (int)EOrderState.等待付款; } } } public class PaiedState : OrderState { public override void SetState(OrderContext context) { if (context.OrderMaster.State != (int)EOrderState.等待付款) { throw new Exception("等待付款订单状态才可改为已付款"); } context.OrderMaster.State = 2; //发送支付成功邮件... //推送支付状态... } } public class CancelState : OrderState { public override void SetState(OrderContext context) { if (context.OrderMaster.State == (int)EOrderState.已付款) { throw new Exception("订单当前状态为支付成功,不允许取消"); } context.OrderMaster.State = (int)EOrderState.已取消; } }
客户端:
static void Main(string[] args) { Order_master orderMaster = new Order_master(); OrderContext context = new OrderContext(orderMaster); context.SetState(orderMaster, EOrderState.等待付款);//将订单状态改为等待付款,并处理相关逻辑 context.SetState(orderMaster, EOrderState.已付款);//将订单状态改为已付款,并处理相关逻辑 context.SetState(orderMaster, EOrderState.已取消);//此处会抛异常,已支付订单不允许取消 Console.ReadKey(); }
原文:https://www.cnblogs.com/fanfan-90/p/12865655.html