写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。
状态模式(State)
对象行为型模式。
目录
一、概述
1.1、直观的理解:
1.2、主要角色:
1.3、描述对象之间关系的UML图:
1.4、适用场景:
二、代码举例
2.1、对象之间的关系用UML图描述如下:
2.2、Java代码如下:
一、概述
1、当一个对象的内在状态改变时改变它的行为,这个对象看起来像是改变了其类。
1.1、直观的理解:
假设一个对象有三种状态,A、B、C。对象的状态从A到B到C顺序轮流变换,由此它的行为也会发跟着发生变化,就像是换了一个对象一样。
当然也不一定非要是A-》B-》C,也可以在状态上加条件语句,使其可以有选择性的改变。就不再举例了。
但此模式具体运行的细节要比上述复杂一些:
1.2、主要角色:
- 环境类:被表示状态的对象,也就是可以改变状态的类
- 状态类:状态的抽象类或接口 + 状态的实现类,表示环境类的某个状态
1.3、描述对象之间关系的UML图:
也就是说每次调用 环境类 里的 更改状态() 方法就会改变状态:
- 调用 环境类 里的 更改状态() 方法
- 更改状态()方法会将自己通过 operation()方法 传递给当前的状态类对象
- 状态类对象收到请求后根据一定的规则,然后将下一个状态再传回给 环境类
1.4、适用场景:
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
二、代码举例
就拿上述例子,状态由A到B再到C,循环变化。这个例子比较简单,就不再详细分析了。但你可以把本例当做一个模板,然后灵活使用:
2.1、对象之间的关系用UML图描述如下:
2.2、Java代码如下:
状态的抽象类:
abstract class State {
public abstract void handle(Context context);
}
状态A:
public class ConcreteStateA extends State {
@Override
public void handle(Context context) {
System.out.println("状态A");
context.setState(new ConcreteStateB());//这里也可以条件语句判断下一个状态是谁
}
}
状态B:
public class ConcreteStateB extends State {
@Override
public void handle(Context context) {
System.out.println("状态B");
context.setState(new ConcreteStateC());//这里也可以条件语句判断下一个状态是谁
}
}
状态C:
public class ConcreteStateC extends State {
@Override
public void handle(Context context) {
System.out.println("状态C");
context.setState(new ConcreteStateA());//这里也可以条件语句判断下一个状态是谁
}
}
环境类:
public class Context {
private State state;
public Context() {
this.state = new ConcreteStateA();
System.out.println("初始化以A开始!");
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void request() {
this.state.handle(this);
}
}
主程序(发起请求的类):
public class Main {
public static void main(String[] args) throws InterruptedException {
Context context = new Context();
while (true) {
context.request();
Thread.sleep(1000);
}
}
}
这里就不再举例了,可以把上面的Java例子复制到你本地,运行main函数试一下加深理解。这些代码都是我自己学习的时候根据一些教材手敲的,不存在bug可以直接运行。
如果觉得本文还不错,就请点个赞给作者一点鼓励吧!如果有建议,也请评论指教和讨论!