模式定义
允许一个对象在其内部状态发生改变时改变它的行为。对象看起来似乎修改了它的类。
状态模式(State Pattern)主要解决的是在开发中时常遇到的根据不同的状态需要进行不同的处理操作的问题,面对这样的问题,大部分人是采用switch-case或者if-else语句 进行处理的,这样会造成一个问题:分支过多,而且如果加入一个新的状态就需要对原来的代码进行编译。
状态模式采用了对这些不同的状态进行封装的方式 处理这类问题,当状态改变的时候进行处理然后再切换到另一种状态,也就是说把状态的切换责任交给了具体的状态类去负责。
模式结构
- Context:上下文环境,定义客户感兴趣的类。
- State:定义一个接口以封装与Context的一个特定的状态相关的行为。
- ConcreteState:具体的状态子类,每一个子类实现一个与Context的一个状态相关的行为。
代码示例
标准模式
下面 我们通过Java代码来诠释一下原始的状态模式。
首先是上下文环境Context :
public class Context {
private State state;//持有一个State类型的对象实例
public void setState(State state) {
this.state = state;
}
public void request(String param) {
//转调state来处理
state.handle(param);
}
}
public interface State {
void handle(String param);
}
State 接口的具体实现类:
public class ConcreteStateA implements State {
@Override
public void handle(String param) {
System.out.println("ConcreteStateA handle param:" + param);
}
}
public class ConcreteStateB implements State {
@Override
public void handle(String param) {
System.out.println("ConcreteStateB handle param:" + param);
}
}
Client:
//创建状态
State state = new ConcreteStateA();
//创建环境
Context context = new Context();
//将状态设置到环境中
context.setState(state);
//请求
context.request("test");
优缺点
优点
- 结构清晰:避免了过多的switch……case或者if……else语句,避免了程序的复杂性,提高系统的可维护性。
- 遵循设计原则:很好的体现了开闭原则和单一职责原则,每个状态都是一个子类,你要增加状态就要增加子类,你要修改状态,只要修改一个子类就可以了。
- 封装性非常好:这也是状态模式的基本要求,状态变换放置到类的内部实现,外部的调用不知道内部如何实现和行为的变换。
状态模式的缺点
- 子类会太多,也就是类膨胀,如果一个事物有很多状态也不稀奇,如果完全使用状态模式就会有太多的子类,不好管理,这个需要使用者衡量。