js设计模式---状态模式

130 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情

状态模式

  • 当一个对象的内部状态发生改变时,会导致其行为的改变,这看起来像是改变了对象
  • 对象有自己的状态
  • 不同状态下执行的逻辑不一样
  • 明确状态和每个状态下执行的动作
  • 用来减少if…else子句 举个例子

电池的三种状态:正常状态(绿色),警告状态(黄色),错误状态(红色)

类图:

image.png 不考虑设计模式的话,简单实现一下:

class  Battery{
  constructor(){
    this.amount = 'high';//电量很高   
  }
}
show(){
  if(this.amount == 'high'){
    console.log('显示绿色');
    this.amount='middle';
  }
  else if(this.amount == 'middle'){
    console.log('显示黄色');
    this.amount = 'low';
  }
  else if(this.amount == 'low'){
    console.log('显示红色');
  }
}
let battery = new Battery();
battery.show();
battery.show();
battery.show();

以上的例子确实可以表示电池展示的三种状态,但是很明显维护不方便,有以下不足:

1.假如电池多了很多其他的状态,那么每次都要新增加很多的if/else,这显然是不可取的,违反了开闭原则。

2.状态切换得不太明显。

可以考虑使用状态模式来优化代码。

把状态的变化变成类的变化,可以把每一份逻辑放到状态类里面去,把显示的逻辑委托给状态对象,但是show内部还要维护状态的变化

请看以下代码:

class SuccessState{
   show(){console.log('显示绿色');}
}
class WarningState{
   show(){console.log('显示黄色');}
}
class ErrorState{
   show(){console.log('显示红色');}
}
class  Battery{
  constructor(){
    this.amount = 'high';
    this.state = new SuccessState();//绿色状态
  }
}
show(){
   this.state.show();
  if(this.amount == 'high'){
    this.amount='middle';
    this.state = new WarningState();
  }
  else if(this.amount == 'middle'){
    this.amount = 'low';
    this.state = new ErrorState();
  }
  
}
let battery = new Battery();
battery.show();
battery.show();
battery.show();

如上代码,不论状态里面要增加多少代码,都是在状态类里面维护,不需要修改show方法。同时,如果要新增其他状态,直接新建一个状态类即可,再在show方法处理。这样show代码也不会过于冗余。还有针对第二点不足,因为增加了状态类,状态切换就比较明显了,代码逻辑更清晰。

以上是关于状态模式的一个小讲解,应用到实际项目中,也是有很多应用场景的。如:

  • 点赞
  • promise
  • React导航
  • 有限状态机