定义
- 用类来表示状态。
- 行为随着状态对象改变而改变。
使用场景
- 代码中包含大量与对象状态有关的条件语句。
- 对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。
UML图
代码示例
公交车状态
// 公交车的状态
public interface State {
//开门
public void openDoor();
//加速
public void speedUp();
}
//停止状态
public class StopState implements State {
private static StopState stopState = new StopState();
public static StopState getInstance(){
return stopState;
}
@Override
public void openDoor() {
System.out.println("公交车可以开门上下乘客");
}
@Override
public void speedUp() {
System.out.println("公交车停止状态无法加速");
}
}
public class RunState implements State {
//使用单例模式
private static RunState runState = new RunState();
public static RunState getInstance(){
return runState;
}
@Override
public void openDoor() {
System.out.println("公交车行驶中无法开门");
}
@Override
public void speedUp() {
System.out.println("公交车行驶中可以加速");
}
}
// 上下文对象
public class Context {
private State state;
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
}
//测试
public class Client {
public static void main(String[] args) {
Context context = new Context();
context.setState(StopState.getInstance());
context.getState().openDoor();
context.getState().speedUp();
context.setState(RunState.getInstance());
context.getState().openDoor();
context.getState().speedUp();
}
}
- 在《图解设计模式》中和网上朋友的示例中;都是将状态切换放在具体状态类中,如:
public class RunState implements State {
public void changeState(Context context){
context.setState(StopState.getInstance());
}
个人认为不合适,比如在上面例子中再加一个等红灯的状态,介于RunState 和StopState之间,那你得去修改具体的状态类,违反了开闭原则。个人觉得状态的切换既然已经在Context维护了,那就直接使用即可。当然如果在程序设计之初,状态的迁移就已经确认并不会出现我所说的情况则也是可以的。
总结
- 用类表示状态,行为随着状态对象改变而改变。
- 遵循单一原则,一种状态一个子类;符合开闭原则,当新增状态时只需添加一个状态子类。