状态模式简介
- 状态模式(state pattern)主要用于解决对象在多种状态转换时候,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转换。
结构
- 1.环境角色(Context):定义客户端需要的接口,并且负责状态的切换。
- 2.抽象状态角色(State):是所有具体状态类的基类或者接口。负责定义该状态下的行为,可以是一个或者多个。
- 3.具体状态角色(Concrete State):实现了抽象状态类的接口,并根据当前状态决定环境角色的行为。
优缺点
- 优点:
- 客户端只需要与上下文对象进行交互,而不需要了解具体状态对象的切换和行为实现细节。
- 状态模式遵循开闭原则,使系统更加可扩展。当需要增加新的状态时,只需添加新的具体状态类,而无需修改上下文对象或其他状态类。
- 避免了使用大量的条件语句来控制对象在不同状态下的行为。它将状态相关的代码分散到各个具体状态类中,使代码更加清晰、可读性更高,易于维护和扩展。
- 状态转换被封装在具体状态类中,可根据需求定义不同的状态切换规则,使得状态转换过程可控、灵活。
- 缺点:
- 状态模式增加了系统中类的数量,引入了更多的类,可能会增加代码的复杂性。
- 对于简单、直接的状态机,使用状态模式可能会显得过于繁琐,增加了代码的冗余。在这种情况下,可以采用简化的条件语句来处理状态转换。
UML图
具体实现
例子:电梯有运行,停止,关闭状态,使用状态模式实现功能。
UML图
代码实现
- 抽象状态类
package com.xxliao.pattern.behavioral.state.demo;
/**
* @author xxliao
* @description: 状态顶层接口 - 抽象状态类
* @date 2024/5/27 15:54
*/
public interface State {
/**
* @description 开启电梯
* @author xxliao
* @date 2024/5/27 15:55
*/
void open();
/**
* @description 电梯运行
* @author xxliao
* @date 2024/5/27 15:56
*/
void run();
/**
* @description 电梯暂停
* @author xxliao
* @date 2024/5/27 15:56
*/
void stop();
/**
* @description 停止电梯
* @author xxliao
* @date 2024/5/27 15:56
*/
void close();
}
- 具体状态类
package com.xxliao.pattern.behavioral.state.demo;
/**
* @author xxliao
* @description: 电梯关闭状态 -具体状态类
* @date 2024/5/27 15:58
*/
public class CloseableState extends LiftState{
@Override
public void open() {
System.out.println("开启电梯。。。");
super.context.setCurrentLiftState(Context.STOPPABLE_STATE);
}
}
package com.xxliao.pattern.behavioral.state.demo;
/**
* @author xxliao
* @description: 电梯运行状态 -- 具体状态类
* @date 2024/5/27 15:58
*/
public class RunnableState extends LiftState{
@Override
public void stop() {
System.out.println("停止电梯。。。");
super.context.setCurrentLiftState(Context.STOPPABLE_STATE);
}
}
package com.xxliao.pattern.behavioral.state.demo;
/**
* @author xxliao
* @description: 电梯暂停状态 --- 具体状态类
* @date 2024/5/27 15:58
*/
public class StoppableState extends LiftState{
@Override
public void run() {
System.out.println("运行电梯。。。");
super.context.setCurrentLiftState(Context.RUNNABLE_STATE);
}
@Override
public void close() {
System.out.println("关闭电梯。。。");
super.context.setCurrentLiftState(Context.CLOSEABLE_STATE);
}
}
- 环境角色(上下文)
package com.xxliao.pattern.behavioral.state.demo;
/**
* @author xxliao
* @description: 环境角色
* @date 2024/5/27 16:27
*/
public class Context {
// 定义所有状态
public final static CloseableState CLOSEABLE_STATE = new CloseableState();
public final static RunnableState RUNNABLE_STATE = new RunnableState();
public final static StoppableState STOPPABLE_STATE = new StoppableState();
private LiftState currentLiftState;
public LiftState getCurrentLiftState() {
return currentLiftState;
}
public void setCurrentLiftState(LiftState currentLiftState) {
this.currentLiftState = currentLiftState;
// 跟新环境对象
this.currentLiftState.setContext(this);
}
public void open() {
this.currentLiftState.open();
}
public void run() {
this.currentLiftState.run();
}
public void stop() {
this.currentLiftState.stop();
}
public void close() {
this.currentLiftState.close();
}
}
- 测试客户端
package com.xxliao.pattern.behavioral.state.demo;
/**
* @author xxliao
* @description: 状态模式 测试客户端
* @date 2024/5/27 16:38
*/
public class Client {
public static void main(String[] args) {
// 创建环境角色
Context context = new Context();
// 设置当前状态
context.setCurrentLiftState(Context.CLOSEABLE_STATE);
// 开启电梯
context.open();
// 运行电梯
context.run();
// 停止电梯
context.stop();
// 关闭电梯
context.close();
}
- 测试结果