状态模式
在状态模式中, 类的行为时给予它的状态改变的。折中类型的设计模式属于行为型模式。
定义
当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。

实现
抽象状态角色State
接口或者抽象类,负责对象状态的定义,并且封装环境角色以实现状态切换。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public interface IState { void open(); void close(); void run(); void stop(); }
public abstract class BaseState implements IState { protected Car context; public void setContext(Car context) { this.context = context; } }
|
具体状态角色ConcreteState
每个具体状态必须完成两个职责:本状态下要做的事情以及本状态如何过渡到其他状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| public class OpenState extends BaseState { public void open() { super.context.setCurrentState(Car.OPEN_STATE); System.out.println("车门已开启"); } public void close() { super.context.setCurrentState(Car.CLOSE_STATE); System.out.println("关闭车门。。。"); } public void run() { System.out.println("开门状态下不允许飙车start"); } public void stop() { System.out.println("开门状态下不允许飙车Stop"); } }
public class StopState extends BaseState { public void open() { super.context.setCurrentState(Car.OPEN_STATE); System.out.println("停车后开启车门"); } public void close() { super.context.setCurrentState(Car.CLOSE_STATE); System.out.println("停车后关闭车门"); } public void run() { super.context.setCurrentState(Car.RUN_STATE); System.out.println("停车后再次跑起来"); } public void stop() { super.context.setCurrentState(Car.STOP_STATE); System.out.println("停车后。。停止不同"); } }
public class RunState extends BaseState { public void open() { System.out.println("飙车时不能开门"); } public void close() { System.out.println("飙车时车门已关闭"); } public void run() { super.context.setCurrentState(Car.RUN_STATE); System.out.println("飙车Run"); } public void stop() { super.context.setCurrentState(Car.STOP_STATE); System.out.println("飙车 stop"); } }
public class CloseState extends BaseState { public void open() { super.context.setCurrentState(Car.OPEN_STATE); System.out.println("开启车门。。。"); } public void close() { System.out.println("车门已经关闭!"); } public void run() { this.context.setCurrentState(Car.RUN_STATE); System.out.println("汽车开始运行。。。"); } public void stop() { this.context.setCurrentState(Car.STOP_STATE); System.out.println("汽车停止。"); } }
|
环境角色Context
定义客户端需要的接口,并且负责具体状态的切换。
把状态对象声明为静态常量,有几个状态对象就声明几个静态常量。
环境角色具有状态抽象角色定义的所有行为,具体执行使用委托方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class Car implements IState {
public static final BaseState OPEN_STATE = new OpenState(); public static final BaseState CLOSE_STATE = new CloseState(); public static final BaseState RUN_STATE = new RunState(); public static final BaseState STOP_STATE = new StopState(); private BaseState currentState; public Car() { this.setCurrentState(CLOSE_STATE); } public BaseState getCurrentState() { return currentState; } public Car setCurrentState(BaseState currentState) { this.currentState = currentState; this.currentState.setContext(this); return this; } public void open() { this.currentState.open(); } public void close() { this.currentState.close(); } public void run() { this.currentState.run(); } public void stop() { this.currentState.stop(); } }
|
使用
结合建造者模式将已有的状态按照一定的顺序再重新组装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Car car = new Car();
car.setCurrentState(Car.CLOSE_STATE);
car.run(); car.stop();
car.run(); car.open();
car.stop();
car.open(); car.close();
|
应用
优点
- 结构清晰
避免过多的switch case和if else,降低了程序的复杂性,提高系统的可维护性。
- 遵循设计原则
遵循了开闭原则以及单一职责原则,每个状态都是一个子类,要增加状态就要增加子类,修改状态时只修改一个子类即可。
- 封装性良好
状态变换防止到类的内部来实现,外部调用不需要知道类内部如何实现状态和行为的变换。
缺点
使用场景
- 行为跟随状态改变而改变的场景
- 条件、分支判断语句的替代