优点 | 缺点 |
---|---|
1. 消除冗余的条件分支,简化代码逻辑。 | 1. 类数量增加,每个状态对应一个类。 |
2. 符合开闭原则,新增状态无需修改现有代码。 | 2. 状态转换逻辑分散,维护成本可能增加。 |
3. 状态行为局部化,职责清晰。 | 3. 过度设计,简单状态机可能无需此模式。 |
/**
* 状态接口:定义电梯各状态下的行为方法
*/
public interface ElevatorState {
void open(); // 开门
void close(); // 关门
void run(); // 运行
void stop(); // 停止
}
/**
* 开门状态:仅允许关门操作
*/
public class OpenState implements ElevatorState {
private final ElevatorContext context;
public OpenState(ElevatorContext context) {
this.context = context;
}
@Override
public void open() {
System.out.println("电梯门已经是打开的");
}
@Override
public void close() {
System.out.println("电梯门关闭");
context.setState(context.getCloseState());
}
@Override
public void run() {
System.out.println("电梯门未关闭,禁止运行");
}
@Override
public void stop() {
System.out.println("电梯已停止");
context.setState(context.getStopState());
}
}
/**
* 关门状态:允许开门、运行或停止
*/
public class CloseState implements ElevatorState {
private final ElevatorContext context;
public CloseState(ElevatorContext context) {
this.context = context;
}
@Override
public void open() {
System.out.println("电梯门打开");
context.setState(context.getOpenState());
}
@Override
public void close() {
System.out.println("电梯门已经是关闭的");
}
@Override
public void run() {
System.out.println("电梯开始运行");
context.setState(context.getRunState());
}
@Override
public void stop() {
System.out.println("电梯停止运行");
context.setState(context.getStopState());
}
}
// 运行状态和停止状态实现类似,此处省略,完整代码参考附录
/**
* 电梯上下文:维护当前状态并提供状态切换方法
*/
public class ElevatorContext {
private ElevatorState currentState;
private final ElevatorState openState;
private final ElevatorState closeState;
private final ElevatorState runState;
private final ElevatorState stopState;
public ElevatorContext() {
this.openState = new OpenState(this);
this.closeState = new CloseState(this);
this.runState = new RunState(this);
this.stopState = new StopState(this);
currentState = stopState; // 初始状态为停止
}
// 委托当前状态处理操作
public void open() {
currentState.open();
}
public void close() {
currentState.close();
}
public void run() {
currentState.run();
}
public void stop() {
currentState.stop();
}
// 状态切换方法
public void setState(ElevatorState state) {
this.currentState = state;
}
// 获取状态实例的方法
public ElevatorState getOpenState() {
return openState;
}
public ElevatorState getCloseState() {
return closeState;
}
public ElevatorState getRunState() {
return runState;
}
public ElevatorState getStopState() {
return stopState;
}
}
public class Client {
public static void main(String[] args) {
ElevatorContext elevator = new ElevatorContext();
System.out.println("===== 初始状态:停止 =====");
elevator.open(); // 停止状态允许开门
System.out.println("\n===== 切换到开门状态 =====");
elevator.close(); // 关门
System.out.println("\n===== 切换到关门状态 =====");
elevator.run(); // 运行
System.out.println("\n===== 切换到运行状态 =====");
elevator.stop(); // 停止
}
}
===== 初始状态:停止 =====
电梯门打开
===== 切换到开门状态 =====
电梯门关闭
===== 切换到关门状态 =====
电梯开始运行
===== 切换到运行状态 =====
电梯停止运行
+----------------+ +----------------+
| Context | <>-----+ | State |
+----------------+ +----------------+
| -state:State | | +handle() |
| +request() | +----------------+
+----------------+ ^
| |
| +----------------+
| | ConcreteStateA |
| +----------------+
| | +handle() |
| +----------------+
| | ConcreteStateB |
| +----------------+
| | +handle() |
| +----------------+
状态模式在 Java 生态中的典型应用包括:
Thread
的 NEW
、RUNNABLE
、BLOCKED
等状态。
掌握该模式能有效管理复杂的状态转换逻辑,增强系统的扩展性和可读性。