状态模式

状态(State)模式又称为状态对象模式(Pattern of Objects for State),状态模式是对象的行为模式。状态模式允许一个对象在其内部状态改变时改变其行为,用于解决系统中复杂对象的状态装换以及不同状态下行为的封装问题。

状态和行为

  所谓对象的状态,通常指的就是对象实例的属性的值;而行为指的就是对象的功能,再具体点说,行为大多可以对应到方法上。

​ 状态模式的功能就是分离状态的行为,通过维护状态的变化,来调用不同状态对应的不同功能。也就是说,状态和行为是相关联的,它们的关系可以描述为:状态决定行为

​ 由于状态是在运行期被改变的,因此行为也会在运行期根据状态的改变而改变。

场景

在一个酒店系统中,房间的状态变化:

  • 空闲
  • 已预订
  • 已入住

状态图

图1

如当前房间状态需要频繁的修改状态时,可以考虑使用状态模式。

模式结构

结构图

图2

  • State抽象状态类:定义了一个接口,用以封装环境(Context)对象的一个特定状态的行为。
  • ConcreteState具体状态类:实现抽象状态接口,实现了一个状态对应的行为。
  • Context环境类:环境类中维护了一个State对象,它是定义了当前的状态。

代码

抽象状态类

1
2
3
4
5
6
7
8
9
package designMode.state;

/**
* @author YoungDream
* @since 2019/4/19 15:29
*/
public interface State {
void handle();
}

具体状态类

1
2
3
4
5
6
public class IdleState implements State {
@Override
public void handle() {
System.out.println("房间没人住...");
}
}
1
2
3
4
5
6
public class ReservationState implements State {
@Override
public void handle() {
System.out.println("房间已经被预定...");
}
}
1
2
3
4
5
6
public class LivedState implements State {
@Override
public void handle() {
System.out.println("房间有人住了...");
}
}

Context环境类

1
2
3
4
5
6
7
8
9
public class Context {
private State state;

public void setState(State state) {
System.out.println("房间状态已经改变...");
this.state = state;
state.handle();
}
}

客户端

1
2
3
4
5
6
7
8
public class Client {
public static void main(String[] args) {
Context context = new Context();
context.setState(new IdleState());
context.setState(new ReservationState());
context.setState(new LivedState());
}
}

控制台

1
2
3
4
5
6
房间状态已经改变...
房间没人住...
房间状态已经改变...
房间已经被预定...
房间状态已经改变...
房间有人住了...

总结

  • 在状态模式中,环境(Context)是持有状态的对象,但是环境(Context)自身并不处理跟状态相关的行为,而是把处理状态的功能委托给了状态对应的状态处理类来处理。
  • 在具体的状态处理类中经常需要获取环境(Context)自身的数据,甚至在必要的时候会回调环境(Context)的方法,因此,通常将环境(Context)自身当作一个参数传递给具体的状态处理类
  • 客户端一般只和环境(Context)交互。客户端可以用状态对象来配置一个环境(Context),一旦配置完毕,就不再需要和状态对象打交道了。客户端通常不负责运行期间状态的维护,也不负责决定后续到底使用哪一个具体的状态处理对象。