总纲
- 设计原则:遵循单一职责、依赖倒置、开闭原则
- 常用场景:一个对象在多个状态下行为不同,且这些状态可互相转换
- 使用概率:20%
- 复杂度:中
- 变化点:状态的种类
- 选择关键点:这些状态是否经常在运行时需要在不同的动态之间相互转换
- 逆鳞:无
- 相关设计模式
- 策略模式:二者的实现方式非常相似,策略接口与状态接口,具体的策略与具体的状态以及二者都拥有的上下文,如果看它们的类图,会发现几乎一模一样,而二者不同的地方就在于,状态模式经常会在处理请求的过程中更改上下文的状态,而策略模式只是按照不同的算法处理算法逻辑,而且从实际场景来讲,顾名思义,状态模式改变的是状态,策略模式改变的是策略
状态模式
uml类图
状态模式uml图.png
状态模式代码
- 状态模式解决的问题:状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。
- 状态模式适用于某一个对象的行为取决于该对象的状态,并且该对象的状态会在运行时转换,又或者有很多的if else判断,而这些判断只是因为状态不同而不断的切换行为。
public class CommonState implements RunState{
public void run(Hero hero) {
//正常跑动则不打印内容,否则会刷屏
}
}
public class SpeedUpState implements RunState{
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{
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{
public void run(Hero hero) {
System.out.println("--------------不能跑动---------------");
try {
Thread.sleep(2000);//假设眩晕持续2秒
} catch (InterruptedException e) {}
hero.setState(Hero.COMMON);
System.out.println("------眩晕状态结束,变为正常状态------");
}
}
//英雄类
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() {
public void run() {
while (!runThread.isInterrupted()) {
state.run(hero);
}
}
});
System.out.println("--------------开始跑动---------------");
runThread.start();
}
private boolean isRunning(){
return runThread != null && !runThread.isInterrupted();
}
}
public class Main {
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();
}
}
网友评论