什么是状态模式?
一个函数原本有很多判断语句,现在把判断语句中的每一种状态封装成一个类,每一个状态类中均有一个handle()函数,该函数能对当前状态做出处理,并且能指明不能处理时的下一个状态类。
状态模式的类图
1.将一个原本的判断结构封装成一个个状态类,每个状态类都有函数handle(Context);
该函数对本状态作出处理,当无法处理时,将context肚子中的成员变量state改成能处理的那个状态类的对象,并执行context的request()函数;
handle()函数实现如下:
public void handle(Context Context){
//判断是否能处理
if(本类能处理){
进行处理;
}
//本类不能处理时
else{
//将context的state变量设为能处理状态类的对象
context.setState(new ConcreteStateB());
//执行context中的request,让下一个状态类处理
context.request();
}
}
2.创建一个Context类,它是提供给客户端执行整个状态模式的接口;
Context类中含有State类型的成员变量state,还有一个handle()函数,该函数用于执行state中的request()函数。
class Context(){
private State state;
public void request(){
this.state.handle();
}
}
3.当客户端调用context的request()函数时,request调用当前context肚子里的那个state的handle函数,如果能处理就处理掉,如果不能处理就将context的state设为能处理的那个状态类,然后再调用request函数。
然后新的处理函数又被执行,直到遇到能执行的处理类为止。
状态模式与职责链模式的异同?
PS:职责链模式的详细介绍请移步至:https://cloud.tencent.com/developer/article/1055962
相同点:状态模式和职责链模式都是将判断语句中的每一个判断分支封装成一个个类。
不同点:状态模式中,每个状态类中既包含了符合条件时的处理方法,也在不符合条件时指明下一个状态类,然后执行该状态类中的处理函数;而在职责链模式中,每一个处理类的处理函数中只有处理当前状态的方法,若不能处理时下一个处理类是由客户端指定的。
综上所述:状态模式的判断流程是在低层模块中定义好的,职责链模式的处理流程是让用户自己设置的。
状态模式的好处
1.遵循了“单一职责原则”:状态模式把一个复杂的判断结构拆分成一个个拥有先后关系的状态类,从而缩小了原本含有大量判断代码的那个函数的体积;原本这个函数中因为有大量的判断导致这个函数责任过大,而现在这个函数的功能不变,但只有一个Context类,从而职责就小了很多。
2.遵循了“开放-封闭原则”:如果此时需要增加判断分支,只要增加一个新的State子类即可,无需像原来那样修改判断语句的代码。
PS:我们要避免函数过长的现象。因为一个函数过长说明这个函数中职责太多,违背了单一职责原则;我们尽量要把长函数分解成一个个小函数,每个小函数只做一件事。
何时使用状态模式?
当一个函数中判断分支很多时,就需要使用状态模式。