前言
很多同学在写代码时,很喜欢使用if else if else if else if else,然后一个方法中,代码量可想而知,在互联网企业高速迭代中,此时要修改一个地方,眼泪水都能看出来,此时就应该想到23中设计模式中的状态模式。
引用
在阿里的编码规范中明确写到,【强制】避免后续代码维护困难,请勿超过3层的if判断
状态模式定义
GOF设计模式的定义是:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了他所属的类。
订单状态变更通知(干货)
常规写法

Order o = new Order() { Id = 1, OrderAmount = 123.45M, OrderNo = "201805240905000000001", OrderStatus = 1 }; if (o.OrderStatus == 1) { } else if (o.OrderStatus == 2) { } else if (o.OrderStatus == 3) { } else if (o.OrderStatus == 4) { } else { }
鉴于此种写法,当状态新增了5,6,7种不同状态时,直接在原有代码中修改,导致整个方法中代码量非常大,不利于维护。
编写可读性,可维护性的代码(状态模式)
定义抽象类,提供状态变更通知
中间状态假设存在
- Create创建订单
- Refund退款
- Finish完成
- Close关闭
- PaySuccess支付成功
订单模型中采用充血模式,默认当前状态为新建订单,执行状态变更通知。
订单类:

public class Order { public long Id { get; set; } public string OrderNo { get; set; } public decimal OrderAmount { get; set; } public byte OrderStatus { get; set; } private OrderState currentState; public OrderState CurrentState { set { currentState = value; } } public Order() { currentState = new CreateOrderState(); } public void StateChangeNotify() { currentState.StateChangeNotify(this); } }
抽象订单状态类
public abstract class OrderState { /// <summary> /// 状态变更通知 /// </summary> /// <param name="order"></param> public abstract void StateChangeNotify(Order order); }
创建订单状态类,继承抽象类
public class CreateOrderState : OrderState { public override void StateChangeNotify(Order order) { if (order.OrderStatus == 1) { Console.WriteLine("订单已经创建,通知优惠券锁定,通知库存锁定"); } else { order.CurrentState = new PaySuccessState(); order.StateChangeNotify(); } } }
支付成功状态类,继承抽象类
public class PaySuccessState : OrderState { public override void StateChangeNotify(Order order) { if (order.OrderStatus == 2) { Console.WriteLine("订单已经支付成功,通知仓库发货,通知优惠券核销"); } else { order.CurrentState = new FinishState(); order.StateChangeNotify(); } } }
执行代码

Order o = new Order() { Id = 1, OrderAmount = 123.45M, OrderNo = "201805240905000000001", OrderStatus = 1 }; o.StateChangeNotify(); o.OrderStatus = 2; o.StateChangeNotify(); o.OrderStatus = 3; o.StateChangeNotify(); o.OrderStatus = 4; o.StateChangeNotify(); o.OrderStatus = 5; o.StateChangeNotify(); Console.ReadLine();
其他代码省略………………
此时可以看出,当我们订单状态不管赋值任何时,直接调用充血模式中的订单对象的状态变更通知StateChangeNotify方法,则自动完成当前状态的变更通知,当我们整个订单状态更多时,我们只需要新增订单状态类继承至订单状态通知抽象类,就能完成对应通知的开发。
最后
状态模式其实只是让你的一大段if else变成了一个个可视化的对象,便于维护,使代码可读性,可维护性大大提高。
附赠测试源码(点我下载)