Java 状态模式(State Pattern)详解
🧠 什么是状态模式?
状态模式是一种行为型设计模式,它允许对象在内部状态改变时改变其行为,状态模式使得一个对象在其状态改变时会表现出不同的行为。通过将不同的状态封装成独立的类,并让对象根据状态来调用不同的类来实现状态的切换。
🎯 使用场景
- 对象的行为依赖于它的状态,并且它必须在运行时根据状态改变它的行为
- 需要有多个状态和状态之间的切换
- 可以避免使用大量的
if-else
或switch
语句
🏗️ 模式结构
- State(抽象状态类):定义一个接口,声明与状态相关的行为
- ConcreteState(具体状态类):实现抽象状态类,定义具体的状态行为
- Context(上下文):维护一个
State
实例,负责在不同状态之间进行切换
✅ 示例:电梯的工作状态
抽象状态类
public interface ElevatorState {
void pressButton();
void openDoor();
void closeDoor();
void move();
}
具体状态类
public class MovingState implements ElevatorState {
private Elevator elevator;
public MovingState(Elevator elevator) {
this.elevator = elevator;
}
@Override
public void pressButton() {
System.out.println("电梯正在移动,不能按按钮!");
}
@Override
public void openDoor() {
System.out.println("电梯正在移动,不能开门!");
}
@Override
public void closeDoor() {
System.out.println("电梯正在移动,门已经关闭!");
}
@Override
public void move() {
System.out.println("电梯正在移动...");
}
}
public class IdleState implements ElevatorState {
private Elevator elevator;
public IdleState(Elevator elevator) {
this.elevator = elevator;
}
@Override
public void pressButton() {
System.out.println("电梯停在楼层,开始移动...");
elevator.setState(new MovingState(elevator));
}
@Override
public void openDoor() {
System.out.println("电梯开门...");
}
@Override
public void closeDoor() {
System.out.println("电梯门关闭...");
}
@Override
public void move() {
System.out.println("电梯停在当前楼层...");
}
}
上下文类
public class Elevator {
private ElevatorState state;
public Elevator() {
this.state = new IdleState(this); // 初始状态为待机状态
}
public void setState(ElevatorState state) {
this.state = state;
}
public void pressButton() {
state.pressButton();
}
public void openDoor() {
state.openDoor();
}
public void closeDoor() {
state.closeDoor();
}
public void move() {
state.move();
}
}
客户端
public class Client {
public static void main(String[] args) {
Elevator elevator = new Elevator();
elevator.pressButton(); // 输出:电梯停在楼层,开始移动...
elevator.move(); // 输出:电梯正在移动...
elevator.openDoor(); // 输出:电梯正在移动,不能开门!
elevator.setState(new IdleState(elevator)); // 切换到待机状态
elevator.openDoor(); // 输出:电梯开门...
}
}
✅ 优点
- 可以避免使用复杂的
if-else
语句或状态机 - 易于添加新的状态和行为
- 状态间的切换变得更加清晰和明确
⚠️ 缺点
- 增加了类的数量
- 状态模式的类设计可能显得较为繁琐
🧩 使用建议
状态模式适用于对象的行为依赖于其状态,并且状态之间有明确的转换关系的场景。典型应用包括工作流、状态机、电梯控制系统等。