设计模式与应用:状态模式
程序员文章站
2022-06-17 17:09:18
...
本文主要介绍状态模式的原理和应用场景,并与策略模式、责任链模式进行对比
简介
State模式也叫状态模式,是行为设计模式的一种。
State模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现的就好像修改了他的类一样。
状态模式的应用场景
主要解决:当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转译到表现不同状态的一系列类当中,可以把复杂的判断逻辑简化。
结构图
角色和职责
- Context 用户对象。拥有State类型的成员,以标识对象的当前状态
- State 接口或基类。封装与Context的特定状态相关的行为
- ConcreteState 接口实现类或子类,实现了一个与Context某个状态相关的行为
实现
状态作用对象
package com.mym.designmodel.State;
/**
* 职责:Context 用户对象。拥有State类型的成员,以标识对象的当前状态
*/
public class Worker {
private State state;
private int hour;
public Worker(){
state = new AMState();
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
public void doWork(){
state.doWorker(this);
state = new AMState();//复原状态。当状态走到最后时复原到最初状态
}
}
抽象状态
package com.mym.designmodel.State;
/**
* 职责:State 接口或基类。封装与Context的特定状态相关的行为
*/
public abstract class State {
public abstract void doWorker(Worker worker);
}
具体各个状态:上午状态
package com.mym.designmodel.State;
/**
* 职责:ConcreteState 接口实现类或子类,实现了一个与Context某个状态相关的行为
*/
public class AMState extends State {
@Override
public void doWorker(Worker worker) {
if(worker.getHour() == 9){
System.out.println("做上午的事情!");
}else{
worker.setState(new PMState());
worker.doWork();
}
}
}
具体各个状态:下午状态
package com.mym.designmodel.State;
/**
* 职责:ConcreteState 接口实现类或子类,实现了一个与Context某个状态相关的行为
*/
public class PMState extends State {
@Override
public void doWorker(Worker worker) {
if(worker.getHour() == 15){
System.out.println("做下午的事情!");
}else{
worker.setState(new NightState());
worker.doWork();
}
}
}
具体各个状态:晚上状态
package com.mym.designmodel.State;
/**
* 职责:ConcreteState 接口实现类或子类,实现了一个与Context某个状态相关的行为
*/
public class NightState extends State {
@Override
public void doWorker(Worker worker) {
if(worker.getHour() == 20){
System.out.println("做晚上的事情!");
}else{
worker.setState(new NoState());
worker.doWork();
}
}
}
具体各个状态:未定义状态
package com.mym.designmodel.State;
/**
* 职责:ConcreteState 接口实现类或子类,实现了一个与Context某个状态相关的行为
*/
public class NoState extends State {
@Override
public void doWorker(Worker worker) {
System.out.println(worker.getHour()+":未定义该做什么事情!");
}
}
测试
package com.mym.designmodel.State;
/**
* 测试
*/
public class MainClass {
public static void main(String[] args) {
Worker worker = new Worker();
worker.setHour(9);
worker.doWork();
worker.setHour(15);
worker.doWork();
worker.setHour(20);
worker.doWork();
worker.setHour(23);
worker.doWork();
//这里测试复原,如果状态没有复原,这里将是未定义状态
worker.setHour(9);
worker.doWork();
}
}
结果:
做上午的事情!
做下午的事情!
做晚上的事情!
23:未定义该做什么事情!
做上午的事情!
需要注意的是状态的复位。如果Worker最后一个状态执行完后,没有复位那么接下来该Worker都处于最后一个状态。执行结果就如下:
做上午的事情!
做下午的事情!
做晚上的事情!
23:未定义该做什么事情!
9:未定义该做什么事情!
状态模式思考于策略模式、责任链模式
状态模式和策略模式实际上都是根据不同条件执行不同事情。但是:
- 状态模式更加关注的是类内部状态迁移,对外(客户端)不可见,客户端只需要按照既定的执行流程调用即可
- 策略模式更加关注的是外部主动选择执行流程。
状态模式之于责任链模式,可能觉得这状态迁移很像责任链链式的执行。但是:
- 状态模式每个状态都是同等层次,没有执行体的上下游
- 责任链模式每个节点都是有执行先后顺序,关注的是整体共同完成一件事。
上一篇: 状态模式