引入
书接上回,我们来聊聊啥是状态模式?
这个模式和之前说的策略模式很像,策略模式是将算法封装起来,而状态模式是将需要经常变化的变量封装起来。
适合用状态模式的场景
- 一个对象的行为依赖于它的状态,并且它必须在运行时根据状态改变它的行为
- 需要编写大量的条件语句来决定一个操作的行为,而且这些条件正好表示对象的一种状态
见过像这样写代码的吗?为了类的行为转变写了几百个条件语句,看得都头疼。
状态模式就可以解决这个问题,将判断语句下放到实现对象(这种可能会导致对象过多,如果行为不复杂,这种结构可以使用一个对照表实现)
状态模式的定义
允许一个对象在其内部状态改变时改变它的行为,对象看起来视乎修改看它的类
状态模式的结构
在结构上也和策略模式相似,这个状态模式将温度这个状态封装起来了。
这个就是把环境对象中的某个属性封装了一下,所以环境对象会引用这个抽象状态
环境
public class Thermometer {
TemperatureState state;//将状态封装成一个类
public void showMessage(){
System.out.println("******************");
state.showTemperature();
System.out.println("******************");
}
public void setState(TemperatureState state){
this.state = state;
}
}
抽象状态
//抽象状态
public interface TemperatureState {
public void showTemperature();
}
具体状态
public class LowState implements TemperatureState{
double n =0 ;
LowState(double n){
if(n<0){
this.n = n;
}
}
@Override
public void showTemperature() {
System.out.println("现在温度是"+ n +" 属于低温度");
}
}
public class MiddleState implements TemperatureState{
double n =15;
MiddleState(double n){
if(n>0&&n<26){
this.n = n;
}
}
@Override
public void showTemperature() {
System.out.println("现在温度是 " + n + " 属于正常温度");
}
}
public class HeightState implements TemperatureState{
double n = 39;
HeightState(double n){
if(n>=39){
this.n = n;
}
}
@Override
public void showTemperature() {
System.out.println("现在温度是 "+ n + "属于高温度");
}
}
应用程序入口
public class Application {
public static void main(String[] args) {
Thermometer thermometer = new Thermometer();//新建一个温度计对象
TemperatureState state = new LowState(-12);
thermometer.setState(state);//状态转换
thermometer.showMessage();
state = new MiddleState(20);
thermometer.setState(state);//状态转换
thermometer.showMessage();
state = new HeightState(39);
thermometer.setState(state);//状态转换
thermometer.showMessage();
}
}
优点
- 使用一个类封装对象的一种状态,很容易增加新的状态
- 在状态模式中,环境中不必出现大量的条件判断语句,环境实例所呈现的状态变得更加清晰、容易理解
- 使用状态模式可以让用户程序很方便地切换环境实例的状态
- 使用状态模式不会让环境的实例中出现内部状态不一致的情况
- 当状态对象没有实例变量时,环境的各个实例可以共享一个状态对象
它和策略模式的异同点
- 状态模式好比于:你在食堂买饭,付款前、付款后、打饭途中,这三个状态都是针对于买饭这一状态的不同处理方法
- 策略模式好比于:你在食堂买饭,是用现金、微信还是支付宝,使用的是不同的支付策略
重要区别:
- 状态模式封装的是属性,重点在各状态之间的切换,从而做不同的事情;而策略模式封装的是算法更侧重于根据具体情况选择策略,并不涉及切换
- 使用状态模式的原因是不同状态下做的事情不同,而使用策略模式的原因是做同一件事不同调用者有不一样的方式