• 状态模式(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变成了一个个可视化的对象,便于维护,使代码可读性,可维护性大大提高。

    附赠测试源码(点我下载

  • 相关阅读:
    ES6你不知道的let关键字及变量的提升
    [ts] Property 'aaa' does not exist on type 'Window' 解决办法
    EXPRESS项目PM2启动NODE_ENV传参数不生效问题解决方法
    react组件开发规范总结
    JavaScript heap out of memory解决方法
    移动端响应式布局--你不知道的CSS3.0媒体查询,解决rem部分情况下无法适配的场景
    在nodeJs的Express框架下用TypeScript编写router路由出现import关键字错误的解决方案
    Zepto的天坑汇总
    mac下CornerstoneSVN出错 Description : The working copy is locked due to a previous error
    bootstrap的popover插件在focus模式时在Safari浏览器无法使用的bug解决方案
  • 原文地址:https://www.cnblogs.com/zhoudemo/p/9081679.html
Copyright © 2020-2023  润新知