状态模式(State)

前言

很多同学在写代码时,很喜欢使用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
            {
            }
View Code

鉴于此种写法,当状态新增了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);
        }
    }
View Code

抽象订单状态类

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();
View Code

其他代码省略………………

 此时可以看出,当我们订单状态不管赋值任何时,直接调用充血模式中的订单对象的状态变更通知StateChangeNotify方法,则自动完成当前状态的变更通知,当我们整个订单状态更多时,我们只需要新增订单状态类继承至订单状态通知抽象类,就能完成对应通知的开发。

最后

状态模式其实只是让你的一大段if else变成了一个个可视化的对象,便于维护,使代码可读性,可维护性大大提高。

附赠测试源码(点我下载

 

posted @ 2018-05-24 11:15  随风ˇ止步  阅读(780)  评论(0编辑  收藏  举报