设计模式之状态模式

场景引出

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

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

优缺点分析

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

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

你可能感兴趣的:(设计模式之状态模式)