状态模式(State Pattern)也被称为状态机模式(State Machine Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。
在状态模式 类的行为是基于它的状态改变的。在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。状态模式 对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
~
本篇文章内容包括:关于状态模式、状态模式 Demo
状态模式(State Pattern)也被称为状态机模式(State Machine Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。
在状态模式 类的行为是基于它的状态改变的。在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。状态模式 对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
状态模式主要包含以下 3 种角色:
通常在以下情况下可以考虑使用状态模式。
# 状态模式优点
# 状态模式缺点
我们此处可以设计一个多线程的状态转换程序,多线程存在 新建、就绪、运行、阻塞和死亡状态。各种状态当遭到相关方法调用/事件触发时会向其他状态转换。
# ThreadContext 环境类(Context)角色
public class ThreadContext {private ThreadState state;ThreadContext() {state = new New();}public ThreadState getState() {return state;}public void setState(ThreadState state) {this.state = state;}public void start() {((New) state).start(this);}public void getCpu() {((Runnable) state).getCpu(this);}public void suspend() {((Running) state).suspend(this);}public void stop() {((Running) state).stop(this);}public void resume() {((Blocked) state).resume(this);}
}
# ThreadState 抽象状态(State)角色
public abstract class ThreadState {/*** 状态名*/protected String stateName;
}
# 新建 New 具体状态(Concrete State)角色
public class New extends ThreadState {public New() {stateName = "新建";System.out.println("线程状态:新建");}public void start(ThreadContext context) {System.out.println("调用 start 方法");if ("新建".equals(stateName)) {context.setState(new Runnable());} else {System.out.println("当前线程不是 New 状态,无法调用 start");}}
}
# 就绪 Runnable 具体状态(Concrete State)角色
public class Runnable extends ThreadState{public Runnable() {stateName = "就绪";System.out.println("线程状态:就绪");}public void getCpu(ThreadContext context) {System.out.println("调用 getCpu 方法");if ("就绪".equals(stateName)) {context.setState(new Running());} else {System.out.println("当前线程不是 就素 状态,无法调用获取 '获取CPU' 的方法");}}
}
# 运行 Running 具体状态(Concrete State)角色
public class Running extends ThreadState {public Running() {stateName = "运行";System.out.println("线程状态:运行");}/*** 挂起* @param context ThreadContext*/public void suspend(ThreadContext context) {System.out.println("调用 suspend 方法");if ("运行".equals(stateName)) {context.setState(new Blocked());} else {System.out.println("当前线程不是 运行 状态,无法调用获取 '挂起' 的方法");}}/*** 停止* @param context ThreadContext*/public void stop(ThreadContext context) {System.out.println("调用 stop 方法");if ("运行".equals(stateName)) {context.setState(new Dead());} else {System.out.println("当前线程不是 运行 状态,无法调用获取 '停止' 的方法");}}
}
# 阻塞 Blocked 具体状态(Concrete State)角色
public class Blocked extends ThreadState {public Blocked() {stateName = "阻塞";System.out.println("线程状态:阻塞");}/*** 状态恢复* @param context ThreadContext*/public void resume(ThreadContext context) {System.out.println("调用 resume 方法");if ("阻塞".equals(stateName)) {context.setState(new Runnable());} else {System.out.println("当前线程不是 阻塞 状态,无法调用获取 '状态恢复' 的方法");}}
}
# 死亡 Dead 具体状态(Concrete State)角色
public class Dead extends ThreadState {public Dead() {stateName = "死亡";System.out.println("线程状态:死亡");}
}
public class Client {public static void main(String[] args) {ThreadContext context = new ThreadContext();context.start();context.getCpu();context.suspend();context.resume();context.getCpu();context.stop();}
}