状态模式:(State Pattern)允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类
状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。
何时使用:
什么是状态机?
UML 类图:
角色组成:
Context.java
public class Context {
private State state;
public Context() {
this.state = new ConcreteStateA(); // 设置初始状态
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void request() {
this.state.handle(this);
}
}
复制代码
State.java
public abstract class State {
public abstract void handle(Context context);
}
复制代码
ConcreteStateA.java、ConcreteStateB.java
public class ConcreteStateA extends State {
@Override
public void handle(Context context) {
System.out.println("ConcreteStateA 状态的 handle 方法");
context.setState(this);
}
}
public class ConcreteStateB extends State {
@Override
public void handle(Context context) {
System.out.println("ConcreteStateB 状态的 handle 方法");
context.setState(this);
}
}
复制代码
测试:
public class Test {
public static void main(String[] args) {
Context context = new Context();
context.request();
System.out.println("当前状态为:" + context.getState());
context.setState(new ConcreteStateB());
context.request();
System.out.println("当前状态为:" + context.getState());
}
}
复制代码
结果:
ConcreteStateA 状态的 handle 方法 当前状态为:通用模板.ConcreteStateA@1b6d3586 ConcreteStateB 状态的 handle 方法 当前状态为:通用模板.ConcreteStateB@4554617c
相信很多人都玩过王者荣耀这款手游,在对局中,王者荣耀里面的英雄遭受到不同的技能或者增益buff会有不同的状态,比如眩晕、加速、减速等等。如果不使用状态模式的话,我们的英雄类会非常的复杂和难以维护。此时使用状态模式才是更好的选择,下面用代码模拟实现一遍。
RunState.java
public interface RunState {
void run(Hero hero);
}
复制代码
CommonState.java、SpeedUpState.java、SpeedDownState.java、SwimState.java
public class CommonState implements RunState {
@Override
public void run(Hero hero) {
// 正常跑动
}
}
public class SpeedUpState implements RunState {
@Override
public void run(Hero hero) {
System.out.println("--------------加速跑动---------------");
try {
Thread.sleep(4000);//假设加速持续4秒
} catch (InterruptedException e) {}
hero.setState(Hero.COMMON);
System.out.println("------加速状态结束,变为正常状态------");
}
}
public class SpeedDownState implements RunState{
@Override
public void run(Hero hero) {
System.out.println("--------------减速跑动---------------");
try {
Thread.sleep(4000);//假设减速持续4秒
} catch (InterruptedException e) {}
hero.setState(Hero.COMMON);
System.out.println("------减速状态结束,变为正常状态------");
}
}
public class SwimState implements RunState{
@Override
public void run(Hero hero) {
System.out.println("--------------不能跑动---------------");
try {
Thread.sleep(2000);//假设眩晕持续2秒
} catch (InterruptedException e) {}
hero.setState(Hero.COMMON);
System.out.println("------眩晕状态结束,变为正常状态------");
}
}
复制代码
Hero.java
public class Hero {
public static final RunState COMMON = new CommonState();//正常状态
public static final RunState SPEED_UP = new SpeedUpState();//加速状态
public static final RunState SPEED_DOWN = new SpeedDownState();//减速状态
public static final RunState SWIM = new SwimState();//眩晕状态
private RunState state = COMMON;//默认是正常状态
private Thread runThread;//跑动线程
//设置状态
public void setState(RunState state) {
this.state = state;
}
//停止跑动
public void stopRun() {
if (isRunning()) {
runThread.interrupt();
}
System.out.println("--------------停止跑动---------------");
}
//开始跑动
public void startRun() {
if (isRunning()) {
return;
}
final Hero hero = this;
runThread = new Thread(new Runnable() {
@Override
public void run() {
while (!runThread.isInterrupted()) {
state.run(hero);
}
}
});
System.out.println("--------------开始跑动---------------");
runThread.start();
}
private boolean isRunning() {
return runThread != null && !runThread.isInterrupted();
}
}
复制代码
测试:
public class Test {
public static void main(String[] args) throws InterruptedException {
Hero hero = new Hero();
hero.startRun();
hero.setState(Hero.SPEED_UP);
Thread.sleep(5000);
hero.setState(Hero.SPEED_DOWN);
Thread.sleep(5000);
hero.setState(Hero.SWIM);
Thread.sleep(5000);
hero.stopRun();
}
}
复制代码
结果:
--------------开始跑动--------------- --------------加速跑动--------------- ------加速状态结束,变为正常状态------ --------------减速跑动--------------- ------减速状态结束,变为正常状态------ --------------不能跑动--------------- ------眩晕状态结束,变为正常状态------ --------------停止跑动---------------
状态模式与策略模式区别 状态模式和策略模式的 UML 一样,但是解决的问题和侧重不一样。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。