目录
状态模式
状态模式是一种较为复杂的设计模式,它用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题.当系统中的某个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时可以使用状态模式.
状态模式概述
状态模式:允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类.
状态模式又名状态对象,它是一种对象行为型模式.
状态模式结构
状态模式包含3个角色:
- 环境类
- 抽象状态类
- 具体状态类

状态模式实现
抽象状态类
abstract class State {
//声明抽象业务方法,不同的具体状态类可以不同的实现
public abstract void handle();
}
具体状态类
class ConcreteState extends State {
public void handle() {
//方法具体实现代码
}
}
环境类
class Context {
private State state; //维持一个对抽象状态对象的引用
private int value; //其他属性值,该属性值的变化可能会导致对象状态发生变化
//设置状态对象
public void setState(State state) {
this.state = state;
}
public void request() {
//其他代码
state.handle(); //调用状态对象的业务方法
//其他代码
}
}
在状态模式结构图中,环境类Context与抽象状态类State之间存在单向关联关系,在Context中定义了一个State对象.在实际使用时,它们之间可能存在更为复杂的关系,State与Context之间可能也存在依赖或者关联关系.
在状态模式的使用过程中,一个对象的状态之间还可以进行相互转换,通常有两种实现状态转换的方式:
- 统一由环境类来负责状态之间的转换,此时,环境类还充当了状态管理器(State Manager)角色,在环境类的业务方法中通过对某些属性值的判断实现状态转换,还可以提供一个专门的方法用于实现属性判断和状态转换.
……
public void changeState() {
//判断属性值,根据属性值进行状态转换
if (value == 0) {
this.setState(new ConcreteStateA());
}
else if (value == 1) {
this.setState(new ConcreteStateB());
}
......
}
……
- 由具体状态类来负责状态之间的转换,可以在具体状态类的业务方法中判断环境类的某些属性值再根据情况为环境类设置新的状态对象,实现状态转换,同样,也可以提供一个专门的方法来负责属性值的判断和状态转换.此时,状态类与环境类之间就将存在依赖或关联关系,因为状态类需要访问环境类中的属性值.
……
public void changeState(Context ctx) {
//根据环境对象中的属性值进行状态转换
if (ctx.getValue() == 1) {
ctx.setState(new ConcreteStateB());
}
else if (ctx.getValue() == 2) {
ctx.setState(new ConcreteStateC());
}
......
}
……
共享状态
在有些情况下,多个环境对象可能需要共享同一个状态,如果希望在系统中实现多个环境对象共享一个或多个状态对象,那么需要将这些状态对象定义为环境类的静态成员对象.
状态模式优/缺点与适用环境
状态模式优点
- 封装了状态的转换规则,可以对状态转换代码进行集中管理,而不是分散在一个个业务方法中.
- 允许状态转换逻辑与状态对象合成一体,而不是提供一个巨大的条件语句块.
- 可以让多个环境对象共享一个状态对象,从而减小系统中对象的个数.
状态模式缺点
- 状态模式会增加系统中类和对象的个数,导致系统运行开销增大.
- 如果使用不当讲导致程序结构和代码的混乱,增加系统设计的难度.
- 状态模式对开闭原则的支持并不太好.
状态模式适用环境
- 对象的行为依赖于它的状态,状态的改变将导致行为的变化.
- 在代码中包含大量与对象状态有关的条件语句.
1万+

被折叠的 条评论
为什么被折叠?



