设计模式(分类) 设计模式(六大原则)
创建型(5种) 工厂方法 抽象工厂模式 单例模式 建造者模式 原型模式
结构型(7种) 适配器模式 装饰器模式 代理模式 外观模式 桥接模式 组合模式 享元模式
行为型(11种) 策略模式 模板方法模式 观察者模式 迭代器模式 责任链模式 命令模式 备忘录模式 状态模式 访问者模式 中介者模式
状态模式(State Pattern)是一种行为设计模式,它允许对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。这种模式主要用于当一个对象的行为依赖于它的状态(即内部状态),并且它必须在运行时根据状态改变它的行为时。
结构: 状态模式主要包含以下几个角色:
- Context(环境类/上下文):定义了客户感兴趣的接口,并维护一个具体状态对象的引用,将与状态相关的操作委托给当前状态对象处理。
- State(抽象状态类):定义一个接口,用以封装使用上下文环境的各个状态所对应的行为。
- ConcreteState(具体状态类):实现抽象状态类定义的接口,每一个具体状态类对应上下文的一个具体状态,负责实现该状态下对应的行为。
原理:
- 上下文对象持有一个状态对象的引用,这个状态对象决定了上下文对象的行为。
- 当上下文对象的内部状态改变时,它会改变所持有的状态对象,从而改变其行为。
- 上下文对象不需要知道具体状态类的细节,只需要通过抽象状态类的接口与状态对象交互。
优缺点: 优点:
- 结构清晰,将状态相关的代码组织在一起,符合单一职责原则。
- 将状态转换的逻辑封装在状态类中,使得状态转换逻辑与上下文对象分离,易于扩展新的状态和转换逻辑。
- 提高了对象的可扩展性和可维护性。
缺点:
- 如果状态过多,会导致类的个数增加,系统复杂度上升。
- 状态模式的使用需要合理判断,避免过度设计。
应用场景:
- UI控件的状态变化,如按钮的禁用/启用状态。
- 状态机的实现,如ATM机的不同操作状态。
- 工作流系统,如订单处理的不同阶段。
代码示例(以Java为例)
// 抽象状态类
interface PlayerState {
void play();
void stop();
void pause();
}
// 具体状态类:播放状态
class PlayingState implements PlayerState {
@Override
public void play() {
System.out.println("Already playing.");
}
@Override
public void stop() {
System.out.println("Stopping the player.");
}
@Override
public void pause() {
System.out.println("Pausing the player.");
// 可能会在这里切换到暂停状态(PauseState)
}
}
// 具体状态类:暂停状态
class PausedState implements PlayerState {
@Override
public void play() {
System.out.println("Resuming the player.");
}
@Override
public void stop() {
System.out.println("Stopping the player.");
}
@Override
public void pause() {
System.out.println("Player is already paused.");
}
}
// 上下文类:播放器
class MediaPlayer {
private PlayerState state;
public MediaPlayer() {
this.state = new StoppedState(); // 初始状态设为停止状态
}
public void setState(PlayerState state) {
this.state = state;
}
public void play() {
state.play();
}
public void stop() {
state.stop();
}
public void pause() {
state.pause();
}
}
// 示例使用
public class StatePatternDemo {
public static void main(String[] args) {
MediaPlayer player = new MediaPlayer();
player.play(); // 输出:Starting the player.
player.pause(); // 输出:Pausing the player.
player.stop(); // 输出:Stopping the player.
}
}
在这个例子中,MediaPlayer
是上下文,它维护了一个PlayerState
的实例,通过调用play()
、stop()
、pause()
等方法,实际上是由当前状态对象决定具体的行为。随着状态的改变,播放器的行为也会相应变化。