设计模式之状态模式
2017-06-14 本文已影响31人
老羊_肖恩
状态模式的定义
状态模式的定义如下:Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. 即:当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。状态模式的核心是封装,状态的变更引起行为的变更。状态模式的通用类图如下所示:

看看状态模式中的三个角色:
- State 抽象状态角色。负责对象状态定义,封装环境角色以实现状态切换。
- ConcreteState 具体状态角色。具体状态角色必须完成两个职责:本状态的行为管理以及趋向状态处理,通俗说就是本状态下做什么,以及本状态如何过渡到其他状态。
- Context 环境角色。定义客户端需要的接口,负责具体状态的切换。
状态模式的通用代码如下:
//抽象状态类
public abstract class State{
//定义一个环境角色,提供子类访问。
protected Context context;
//设置环境角色
public void setContext(Context context){
this.context = context;
}
//行为1
public abstract void handle1();
//行为2
public abstract void handle2();
}
//具体状态角色1
public class ConcreteState1 extends State{
@Override
public void handle1() {
//本状态下必须处理的逻辑
System.out.println("状态1 必须处理的逻辑...");
}
@Override
public void handle2() {
//设置当前状态为state2
super.context.setCurrentState(Context.STATE2);
System.out.println("从 state1 过渡到 state2...");
//过渡到state2, 由Context实现
super.context.handle2();
}
}
//具体状态角色2
public class ConcreteState2 extends State{
@Override
public void handle1() {
//设置当前状态为state1
super.context.setCurrentState(Context.STATE1);
System.out.println("从 state2 过渡到 state1...");
//过渡到state1
super.context.handle1();
}
@Override
public void handle2() {
//本状态下必须处理的逻辑
System.out.println("状态2 必须处理的逻辑...");
}
}
//环境角色
public class Context{
//定义状态
public final static State STATE1 = new ConcreteState1();
public final static State STATE2 = new ConcreteState2();
//当前状态
private State currentState;
//获取当前状态
public State getCurrentState(){
return this.currentState;
}
//设置当前状态
public void setCurrentState(State state){
this.currentState = state;
//切换状态
this.currentState.setContext(this);
}
//委托行为1
public void handle1(){
this.currentState.handle1();
}
//委托行为2
public void handle2(){
this.currentState.handle2();
}
}
//客户端
public class StateClient{
public static void main(String[] args) {
//定义环境角色
Context context = new Context();
//初始化状态
context.setCurrentState(new ConcreteState1());
//执行行为
context.handle1();
context.handle2();
System.out.println("----------------------");
//初始化状态
context.setCurrentState(new ConcreteState2());
//执行行为
context.handle1();
context.handle2();
}
}
通用代码运行结果如下:
状态1 必须处理的逻辑...
从 state1 过渡到 state2...
状态2 必须处理的逻辑...
----------------------
从 state2 过渡到 state1...
状态1 必须处理的逻辑...
从 state1 过渡到 state2...
状态2 必须处理的逻辑...
状态模式的应用
状态模式的优点
- 结构清晰。避免了过多的if...else语句的试用,避免了程序的复杂性,提高了系统的可维护性。
- 遵循设计原则。很好地体现了开闭原则和单一职责原则。
- 封装性非常好。状态变化放置到类的内部实现,外部的调用不知道类内部如何实现状态和行为的变化。
状态模式的缺点
- 子类太多。当事物状态比较多时,子类会膨胀。
状态模式的使用场景
- 行为随状态改变而改变的场景。
- 条件、判断语句的替代者。
《注》以上内容总结自秦小波-《设计模式之禅》,仅为个人学习笔记