美文网首页
设计模式之状态模式

设计模式之状态模式

作者: SCQ000 | 来源:发表于2017-02-06 09:31 被阅读11次

    场景引出

    假设你有这样一种需求:零售系统中的订单通常有多种状态,包括了从支付、出库、发货、签收等各种状态。而系统则需要根据这些不同的订单状态分别做对应的处理。一个比较符合直觉的解决方案可能就是用多重条件分支语句。就像下面这样:

    if(order.state === 'payment') {
      //处理支付订单
    } else if(order.state === 'outbound') {
      //处理出库
    }else if(order.state === 'delivery') {
      //处理发货
    }else if(order.state === 'received') {
      //处理签收
    }
    

    但是,为了在后续代码有更好的可维护性,有没有更好的解决方案呢?这里就引出了状态模式。

    状态模式的定义

    状态模式(State Pattern): 允许一个对象在其内部状态改变时改变它的行为。在设计模式中,它是处于对象行为型模式。

    • 上下文(context): 环境,即具体执行的上下文。是包含了状态的对象,可以充当状态管理器(state manager)对状态进行切换操作。
    • 抽象状态(State): 抽象状态用以定义各种状态间公用的方法和接口,以便继承。
    • 具体状态(ConcreteState): 将对象的各种状态抽象出来,具体的业务逻辑也是在具体状态类中实现。同时,各个状态之间的转换关系也在具体状态类中得以体现。

    解决方案

    至此,我们就可以将上述的场景代码改成如下所示:

    var State = function() {};
    State.prototype.handle = function() {};
    
    var Order = function() {
      this.state = new PaymentState(); //假设初始化状态为支付状态。
      this.setState = function(state) {
        this.state = state;
      }
    };
    
    //处理订单
    Order.prototype.handle = function() {
        this.state.handle(this);
    }
    
    //支付状态
    var PaymentState = function() {
      this.handle = function(order) {
        //利用传进来的order处理
        ...
        //订单处理完毕后将转换状态
        order.setState(new OutboundState());
      }
    };
    
    //出库状态
    var OutboundState = function() {
      this.handle = function(order) {
        ...
        order.setState(new )
      }
    }
    
    var order = new Order();
    order.handle();
    
    

    优缺点分析

    状态模式和策略模式有点类似,都是讲具体的业务行为委托给具体的子类,从而避免多重条件分支语句造成的代码维护和耦合问题。

    但同时使用状态模式,不可避免地将会增加状态类和系统类的个数,当状态数量较多以及转换规则复杂时,容易造成代码混乱。如果需要增加新的状态时候,也需要修改具体状态转换的代码,以及相关的具体状态类的代码。

    相关文章

      网友评论

          本文标题:设计模式之状态模式

          本文链接:https://www.haomeiwen.com/subject/xduyittx.html