1.定义
- 不同的状态抽象为不同的对象
- 将对象的行为包装在不同的状态对象中
2.适用场景
当对象的行为与状态有关时,此模式可以避免过多的分支判断语句。
状态模式实质上将每一个条件分支放到一个独立的类中,每一个对象不依赖其他对象而独立变化,通过多态来达到去除if-else分支判断语句。
3.UML类图
- 角色说明
IState: 状态抽象接口, 定义一组接口,表示改状态下的行为
ConcreteStateA: 具体状态类A,实现当前状态下的各个接口行为
ConcreteStateB: 具体状态类B
Context: 上下文类,持有一个IState的实例,定义了当前环境下的状态 - 要点
与策略模式的UML一样,注意区分二者的本质特点:
4.UML示例代码
/**
* Copyright (C), 2016-2020
* FileName: IState
* Author: wei.zheng
* Date: 2019/12/7 21:36
* Description: 抽象状态接口
*/
public interface IState {
void nextChannel();
void prevChannel();
void volumeUp();
void volumeDown();
}
/**
* Copyright (C), 2016-2020
* FileName: PowerOnState
* Author: wei.zheng
* Date: 2019/12/7 21:38
* Description: 开机状态: 实现各个接口
*/
public class PowerOnState implements IState {
@Override
public void nextChannel() {
System.out.println("下一个频道");
}
@Override
public void prevChannel() {
System.out.println("上一个频道");
}
@Override
public void volumeUp() {
System.out.println("音量up");
}
@Override
public void volumeDown() {
System.out.println("音量down");
}
}
/**
* Copyright (C), 2016-2020
* FileName: PowerOffState
* Author: wei.zheng
* Date: 2019/12/7 21:39
* Description: 关机状态: 各个接口空实现
*/
public class PowerOffState implements IState {
@Override
public void nextChannel() {
}
@Override
public void prevChannel() {
}
@Override
public void volumeUp() {
}
@Override
public void volumeDown() {
}
}
/**
* Copyright (C), 2016-2020
* FileName: ControllerContext
* Author: wei.zheng
* Date: 2019/12/7 21:41
* Description: 遥控器Context类
*/
public class ControllerContext {
private IState mState;
public void setState(IState state) {
this.mState = state;
}
public void powerOn() {
setState(new PowerOnState());
System.out.println("开机");
}
public void powerOff() {
setState(new PowerOffState());
System.out.println("关机");
}
public void nextChannel() {
mState.nextChannel();
}
public void prevChannel() {
mState.prevChannel();
}
public void volumeUp() {
mState.volumeUp();
}
public void volumeDown() {
mState.volumeDown();
}
}
/**
* Copyright (C), 2016-2020
* FileName: Client
* Author: wei.zheng
* Date: 2019/12/7 21:44
* Description: 用户类
*/
public class Client {
public static void main(String[] args) {
ControllerContext mController = new ControllerContext();
// 开机
mController.powerOn();
mController.nextChannel();
mController.volumeUp();
// 关机
mController.powerOff();
mController.nextChannel();
mController.volumeUp();
}
}
输出结果:
2019-12-07 21:54:45.550 6902-6902/com.example.state I/System.out: 开机
2019-12-07 21:54:45.550 6902-6902/com.example.state I/System.out: 下一个频道
2019-12-07 21:54:45.550 6902-6902/com.example.state I/System.out: 音量up
2019-12-07 21:54:45.551 6902-6902/com.example.state I/System.out: 关机
5.总结
- 与策略模式的比较
状态模式将每个状态都定义为对象,其行为是平行的、不可替换的;
策略模式的行为彼此独立,可互相替换。 - 优缺点
优点:将if-else条件判断转换为多个状态类,保证了可扩展性与维护性
缺点:增加了系统类与对象的个数