意图
状态模式的意思是让一个对象在其内部状态改变的时候,其行为也随之改变。
什么情况下使用状态模式
(1)一个对象的行为依赖于它所处的状态,对象的行为随着状态的改变而改变。
(2)对象在某个方法里有大量的依赖于对象状态的条件判断语句。状态模式把条件转移语句的每一个每支都包装到一个单独的类里。维护这些独立的类也就不再影响到系统的其他部分。
类图
角色
(1)环境(Context)角色:环境角色持有一个具体状态类的实例,决定当前的状态。它将依赖于状态的方法调用都委托给State对象。
(2)状态(State)角色:定义了环境类中所有依赖于状态的方法,是一个抽象类或接口。
(3)具体状态(ConcreteState)角色:实现State接口,实现了某一状态下的具体方法。
讨论
(1)状态模式中,谁来管理状态的切换是一个问题。是由环境类来管理还是由具体状态类来管理呢?如果转换条件是固定的,那么状态的切换应当由Context来做。其它情况下,可以让State子类来决定下一个状态是什么。
(2)状态对象的创建和销毁。一种方法是动态地创建需要的状态对象,当不再需要某一状态对象的时候就将其销毁(在Java中就是将句柄赋值为null)。还有一种方法就是一开始就创建所有的状态对象,然后切换状态的时候就是重复使用这些状态对象。
(3)状态对象可以保存一个环境类对象的引用,这样状态对象就可以调用环境对象,也可以为环境对象切换状态。
源代码
package
public
protected
public
public
public
this.context=c;
}
}
package
public
public
public
currentState.openDoor();
}
public
currentState.closeDoor();
}
public
this.currentState=state;
state.setContext(this);
}
}
package
public
private
private
public
return
}
@Override
public
super.context.setState(ClosedState.getInstance());
System.out.println("开着的门被关上了");
}
@Override
public
System.out.println("门已经是开着的了");
}
}
package
public
private
private
public
return
}
@Override
public
System.out.println("门已经是关着的了");
}
@Override
public
super.context.setState(OpenState.getInstance());
System.out.println("关着的门被打开了");
}
}
package
public
public
Context
context.setState(ClosedState.getInstance());
context.openDoor();
context.openDoor();
context.closeDoor();
context.closeDoor();
context.openDoor();
}
}