关于javascript:精读设计模式-State-状态模式

39次阅读

共计 2386 个字符,预计需要花费 6 分钟才能阅读完成。

State(状态模式)

State(状态模式)属于行为型模式。

用意:容许一个对象在其外部状态扭转时扭转它的行为。对象看起来仿佛批改了它的类。

简略来说,就是将“一个大 class + 一堆 if else”替换为“一堆小 class”。一堆小 class 就是一堆状态,用一堆状态代替 if else 会更好拓展与保护。

举例子

如果看不懂下面的用意介绍,没有关系,设计模式须要在日常工作里用起来,联合例子能够加深你的了解,上面我筹备了三个例子,让你领会什么场景下会用到这种设计模式。

团队接口人

团队是由很多同学组成的,但有一位接口人 TL,这位 TL 可能一会儿和产品经理谈需要,一会儿和其余 TL 谈布局,一会儿和 HR 谈人事,总之要做很多事件,很显然一个人是忙不过来的。TL 通过将工作分发给团队中每个同学,而不让他们间接和产品经理、其余 TL、HR 接触,那么这位 TL 的办事效率就会相当高,因为每个同学只负责一块具体的业务,而 TL 在不同时刻叫上不同的同学,让他们露面解决他们负责的业余畛域问题,那么在里面看,这位 TL 团队能力很广,在内看,每个人负责的事件也比拟繁多。

台灯按钮

咱们常常会看到只有一个按钮的台灯,然而能够通过按钮调节亮度,大略是如下一个循环“关 -> 弱光 -> 亮 -> 强光 -> 关”,那么每次按按钮后,要跳转到什么状态,其实和以后状态无关。咱们能够用 if else 解决这个问题,也能够用状态模式解决。

用状态模式解决,就是将这四个状态封装为四个类,每个类都执行按下按钮后要跳转到的状态,这样将来新增一种模式,只有扭转局部类即可。

数据库连接器

在数据库连贯前后,这个连接器的状态显然十分不同,咱们如果仅用一个类形容数据库连接器,则外部免不了写大量分支语句进行状态判断。那么此时有更好的计划吗?状态模式通知咱们,能够创立多个不同状态类,比方连贯前、连贯中、连贯后三种状态类,在不同时刻外部会替换为不同的子类,它们都继承同样的父类,所以里面看上去不须要感知外部的状态变动,外部又能够进行状态拆分,进行更好的保护。

用意解释

用意:容许一个对象在其外部状态扭转时扭转它的行为。对象看起来仿佛批改了它的类。

重点在“外部状态”的了解,也就是状态扭转是由对象外部触发的,而不是内部,所以 内部基本无需关怀对象是否用了状态模式 ,拿数据库连接器的例子来说,不论这个类是用 if else 堆砌的,还是用状态模式做的,都齐全不障碍它对外提供的稳固 API(接口问题),所以状态模式本质上是一种内聚的设计模式。

结构图

  • State: 状态接口,类比为台灯状态。
  • ConcreteState: 具体状态,都继承于 State,类比为台灯的强光、弱光状态。

代码例子

上面例子应用 typescript 编写。

// 定义状态接口
interface State {
  // 模仿台灯点亮
  show: () => string}

class Light1 implements State {constructor(context: Context) {this.context = context}

  show() {return '关灯'}

  // 按下按钮
  public click() {this.context.setState(new Light2(this.context))
  }
}

class Light2 implements State {constructor(context: Context) {this.context = context}

  show() {return '弱光'}

  // 按下按钮
  public click() {this.context.setState(new Light3(this.context))
  }
}

class Light3 implements State {constructor(context: Context) {this.context = context}

  show() {return '亮'}

  // 按下按钮
  public click() {this.context.setState(new Light4(this.context))
  }
}

class Light4 implements State {constructor(context: Context) {this.context = context}

  show() {return '强光'}

  // 按下按钮
  public click() {this.context.setState(new Light1(this.context))
  }
}

// 台灯
public class Lamp {
  // 以后状态
  private currentState = new Light1(this)

  protected setState(state: State) {this.currentState = state}

  // 按下按钮
  public click() {this.getState().click()}
}

const lamp = new Lamp() // 敞开
lamp.click() // 弱光
lamp.click() // 亮
lamp.click() // 强光
lamp.click() // 敞开 

其实有很多种形式来实现,不用拘泥于模式,大体上只有保障由多个类实现不同状态,每个类实现到下一个状态切换就好了。

弊病

该用 if else 的时候还是要用,不要凡是遇到 if else 就应用状态模式,那样就是书读傻了。肯定要判断,是否各状态间差别很大,且应用状态模式后维护性比 if else 更好,才应该用状态模式。

总结

在适合场景下,状态模式能够使代码更合乎开闭准则,每个类独立保护时,逻辑也更精简、聚焦,更易保护。

探讨地址是:精读《设计模式 – State 状态模式》· Issue #303 · dt-fe/weekly

如果你想参加探讨,请 点击这里,每周都有新的主题,周末或周一公布。前端精读 – 帮你筛选靠谱的内容。

关注 前端精读微信公众号

版权申明:自在转载 - 非商用 - 非衍生 - 放弃署名(创意共享 3.0 许可证)

正文完
 0