Java设计模式(20)之状态模式
程序员文章站
2022-06-17 17:09:42
...
状态模式
允许对象在内部状态改变时,改变它的行为,对象看起来好像修改了它的类。当一个对象的行为改变根据它的状态而改变时,就可以使用状态模式。
类型:
行为型模式(类的状态的行为型模式)
状态模式的几个角色:
具体对象Context:维护具体状态的实例,定义当前的状态
抽象状态对象State:抽象状态接口,定义状态改变时Context对象行为改变的方法
具体状态对象ConcreteState:具体的状态对象,每一种状态对应Context对象的一种具体的行为。
状态模式的关系图:
状态模式示例:
具体对象Context:
/**
* Create by zhaihongwei on 2018/4/2
* Context对象
*/
public class LightContext {
public State state;
public LightContext() {
// 灯的默认状态为关闭状态
this.state = new LightOffState();
}
/**
* 灯的开关,外界没有办法改变灯的打开或者关闭
* 由灯的状态自己改变
*/
public void onoffSwitch() {
state.operationByState(this);
}
}
抽象状态对象State:
/**
* Create by zhaihongwei on 2018/4/2
* 抽象的状态对象
*/
public interface State {
void operationByState(LightContext light);
}
具体状态对象ConcreteState:(灯的开启状态,灯的关闭状态)
/**
* Create by zhaihongwei on 2018/4/2
* 灯的开启状态
*/
public class LightOnState implements State {
@Override
/**
* 灯在打开的情况下,再次按下开关,灯将关闭
*/
public void operationByState(LightContext light) {
System.out.println("灯关闭了!");
// 灯打开(一次点击开关按钮)之后,将灯的开关状态修改为关闭状态
light.state = new LightOffState();
}
}
/**
* Create by zhaihongwei on 2018/4/2
* 灯的关闭状态
*/
public class LightOffState implements State{
@Override
/**
* 灯在关闭的情况下,再次按下开关,灯将打开
*/
public void operationByState(LightContext light) {
System.out.println("灯打开了!");
// 灯关闭(一次点击开关按钮)之后,将灯的开关状态修改为开启状态
light.state = new LightOnState();
}
}
测试类:
/**
* Create by zhaihongwei on 2018/4/2
*/
public class StateTest {
public static void main(String[] args) {
// 创建灯对象
LightContext lightContext = new LightContext();
// 按一次开关
lightContext.onoffSwitch();
// 再按一次开关
lightContext.onoffSwitch();
}
}
测试结果:
灯打开了!
灯关闭了!
总结:
通过上面的例子,可以看到通过状态模式将灯的状态进行了封装,将开灯和关灯的操作委托给了灯的开状态和关状态,随着状态的改变灯的行为也发生了改变。
思考:
如果之前你有学习过策略模式,就会发现状态模式的关系图和策略模式的关系图基本上是一样的,没有看到策略模式的可以看这篇文章:策略模式
虽然说关系图是一样的,但是两种模式的具体关注点是不同的:
- 对于状态模式:将Context的行为改变封装到了状态对象中,Context的行为随着状态的改变而改变,而外部不需要知道内部状态的具体实现规则,只知道Context的行为改变了(如按了开关之后,知道灯开了,但并不知道灯的状态也改变了)
- 对于策略模式:通常是外部主动根据具体情况选择了对应的策略(如警察叔叔对象在司机对象吹完酒精检测仪之后,根据结果选择了醉酒驾驶的策略)
状态模式的优缺点:
优点:
- 将特定状态对应的行为局部化,将不同状态的行为分割开来
- 将具体的状态改变交由子类来完成,避免了互相之间的依赖
缺点:
- 具体状态类的增加