1.状态模式的定义
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
2.状态模式示意类
Context类:环境类,包括一些内部状态。 State类—抽象状态类,state定义的一个所有的具体状态的共同接口,任何状态都能实现这个接口,这样一来状态之间可以互相转换。 ConcreteState类:具体的状态类。用于处理来自Context的请求,每一个ConcreteState都实现了context一个状态相关的行为,所以当context改变状态时,行为也会跟着改变。
3.状态模式结构图
4.示例代码
实例:push显示红-〉黄-〉绿,pull显示绿-〉黄-〉红
public interface State
{
public void handlePush(Context context);
public void handlePull(Context context);
public String getColor();
} public class Context
{
private State state = null;
public State getState()
{
return state;
}
public void setState(final State state) {
this.state = state;
}
public void push() {
state.handlePush(this);
}
public void pull() {
state.handlePull(this);
}
}
//RED public class ConcreteStateA implements State {
@Override
public void handlePush(final Context context) {
System.out.print(this.getColor());
final State state = new ConcreteStateB();
context.setState(state);
state.handlePush(context);
}
@Override
public void handlePull(final Context context) {
System.out.print(this.getColor());
}
@Override
public String getColor() {
return "RED";
}
}
//YELLOW public class ConcreteStateB implements State
{
@Override
public void handlePush(final Context context) {
System.out.print(this.getColor());
final State state = new ConcreteStateC();
context.setState(state); state.handlePush(context);
}
@Override
public void handlePull(final Context context) {
System.out.print(this.getColor());
final State state = new ConcreteStateA();
context.setState(state);
state.handlePull(context); }
@Override
public String getColor() {
return "YELLOW";
}
}
//green public class ConcreteStateC implements State
{
@Override
public void handlePush(final Context context) {
System.out.print(this.getColor());
}
@Override
public void handlePull(final Context context)
{
System.out.print(this.getColor());
final State state = new ConcreteStateB();
context.setState(state);
state.handlePull(context);
}
@Override
public String getColor()
{
return "GREEN";
}
}
public class Client {
public static void main(final String[] args) {
// YTODO Auto-generated method stub final Context context = new Context();
context.setState(new ConcreteStateA());
System.out.println("PUSH:");
context.push();
System.out.println("\nPULL:"); context.pull(); }
}
结果: PUSH: REDYELLOWGREEN PULL: GREENYELLOWRED
总结:
状态模式的优点是 : 将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。 特定状态的相关的行为都放入一个对象中,由于所有的与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类,可以很容易的增加新的状态和转换 。而且消除了庞大的条件分支语句,通过各种状态把逻辑分布到state的子类之中,来减少相互之间的依赖。
#注意#:使用前需要枚举可能的状态,否则可能也会有一些工作量。例如新增一个预留状态,除了新增一个预留状态ConcreteState类,还需要在状态State接口中新增预留接口,Room类中新增预留状态,各个ConcreteState接口类增加与预留状态相互的关系行为。 这也大致体现了状态模式的缺点,必然性的会增加系统中类和对象的个数。使用不当会导致系统的复杂性增加。如果预先状态设计不能全面,对开闭原则支持的就不太好,对于互相切换状态的系统,新增新的状态会修改那些负责状态转换和对应类的代码。