状态模式(state pattern),通过一个类的内部状态的改变,来改变其行为,这就是状态模式。
状态模式也会定义一系列类簇,每个类中具有转换到下一个状态的逻辑,通过一个统一的上下文类,来使用状态类的功能。
比如我们生活中的红绿灯,红灯亮一段时间转为绿灯,绿灯两一段时间转为黄灯,黄灯两一段时间转为红灯。路口的红绿灯就这样一直循环下去。
涉及角色:
1、抽象状态角色:定义状态行为
2、具体状态角色:实现具体的职责,同时定义状态变化的方式
3、上下文角色:持有状态(保存状态),并使用状态类的功能
我们就以这个例子来看一下代码:
1、定义抽象状态类
package com.itzhimei.study.design.state;
/**
* www.itzhimei.com
* 状态模式--状态抽象
*/
public interface IState {
void doHandle();
void changeState(Context context);
}
2、定义具体状态类,包括红灯状态、绿灯状态、黄灯状态
package com.itzhimei.study.design.state;
/**
* www.itzhimei.com
* 状态模式--红灯
*/
public class RedState implements IState {
@Override
public void doHandle() {
System.out.println("红灯状态");
}
@Override
public void changeState(Context context) {
System.out.println("------变换状态------");
context.setState(new GreenState());
}
}
package com.itzhimei.study.design.state;
/**
* www.itzhimei.com
* 状态模式--绿灯
*/
public class GreenState implements IState {
@Override
public void doHandle() {
System.out.println("绿灯状态");
}
@Override
public void changeState(Context context) {
System.out.println("------变换状态------");
context.setState(new YellowState());
}
}
package com.itzhimei.study.design.state;
/**
* www.itzhimei.com
* 状态模式--黄灯
*/
public class YellowState implements IState {
@Override
public void doHandle() {
System.out.println("黄灯状态");
}
@Override
public void changeState(Context context) {
System.out.println("------变换状态------");
context.setState(new RedState());
}
}
3、定义上下文类
package com.itzhimei.study.design.state;
/**
* www.itzhimei.com
* 状态模式--上下文
*/
public class Context {
private IState state;
public void setState(IState state) {
this.state = state;
}
public void doHandle() {
this.state.doHandle();
this.state.changeState(this);
}
}
4、测试
package com.itzhimei.study.design.state;
/**
* www.itzhimei.com
* 状态模式--测试
*/
public class Client {
public static void main(String[] args) {
IState red = new RedState();
Context context = new Context();
context.setState(red);
context.doHandle();
context.doHandle();
context.doHandle();
}
}
输出结果:
红灯状态
------变换状态------
绿灯状态
------变换状态------
黄灯状态
------变换状态------
类关系图:
我们现在来分析一下代码,在三个红黄绿的状态类中,一个doHandle()方法,是其自己工作的职责,也就是当前是红灯状态,那么红灯就要亮一段时间,来控制哪条路不能通行;另一个changeState(Context context)方法,持有一个上下文类,这个方法是,这个context的作用就是持有变更的状态类,也就是接收不断被更新的状态类,我们demo中按照红灯转绿灯,绿灯转黄灯,黄灯转红灯的顺序,在各自状态类中定义了下一个状态是谁。
最后,我们在main函数中可以看到,通过调用上下文的context.doHandle(),就可以持续产生红绿灯的状态变化。
就好比红绿灯的始终都是这个一个红绿灯,但是通过控制信号,就能持续产生信号灯颜色的变化,这就是状态模式的精髓了。
在应对复杂状态变化的场景,状态模式往往能发挥巨大作用。