当前位置: 首页 > article >正文

状态模式详解

状态模式详解
1. 定义与特点
状态模式(State Pattern)是一种行为型设计模式,它允许一个对象在其内部状态改变时改变其行为。这种模式通过将每个状态封装为一个单独的类来实现状态的转换。状态模式的主要特点是将对象的行为和状态相关联,使得对象在不同状态下可以有不同的行为表现。
2. 结构与角色
状态模式包含以下几个核心角色:
•  Context(环境):维护一个对抽象状态对象的引用,可以定义当前的状态,以及在状态改变时切换状态。
•  State(抽象状态):定义一个接口或抽象类,声明具体状态类的方法,用于封装与Context的一个特定状态相关的行为。
•  ConcreteState(具体状态):实现抽象状态定义的接口或抽象类,具体实现与Context对象的状态相关的行为。
3. 适用场景
状态模式适用于以下场景:
•  对象的行为依赖于状态变化时,并且行为会随着状态的不同而发生变化。
•  对象的状态变化频繁,而且状态之间的切换逻辑复杂,状态模式可以很好地管理这些状态。
•  需要避免使用大量条件判断来实现不同状态下的行为时,状态模式是一个更优雅的解决方案。
4. 优点
•  状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。
•  减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
•  有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。
5. 缺点
•  状态模式的使用必然会增加系统的类与对象的个数。
•  状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。
6. 代码示例
以下是一个简单的状态模式的代码示例,展示了如何实现一个视频播放器的状态管理:
// 状态接口
public interface State {
    void insertQuarter();
    void ejectQuarter();
    void pressPlay();
    void pressStop();
    void pressPause();
}

// 具体状态类:播放状态
public class PlayingState implements State {
    private Jukebox jukebox;

    public PlayingState(Jukebox jukebox) {
        this.jukebox = jukebox;
    }

    @Override
    public void insertQuarter() {
        System.out.println("Please remove the quarter before inserting another.");
    }

    @Override
    public void ejectQuarter() {
        System.out.println("Quarter returned.");
        jukebox.setState(jukebox.getNoQuarterState());
    }

    @Override
    public void pressPlay() {
        System.out.println("Song is playing.");
    }

    @Override
    public void pressStop() {
        System.out.println("Song is stopped.");
        jukebox.setState(jukebox.getNoQuarterState());
    }

    @Override
    public void pressPause() {
        System.out.println("Song is paused.");
        jukebox.setState(jukebox.getPausedState());
    }
}

// 上下文环境类
public class Jukebox {
    private State state;
    private int quarterCounter = 0;

    public Jukebox() {
        this.state = this.getNoQuarterState();
    }

    public void setState(State state) {
        this.state = state;
    }

    public void insertQuarter() {
        state.insertQuarter();
    }

    public void ejectQuarter() {
        state.ejectQuarter();
    }

    public void pressPlay() {
        state.pressPlay();
    }

    public void pressStop() {
        state.pressStop();
    }

    public void pressPause() {
        state.pressPause();
    }

    public State getNoQuarterState() {
        return new NoQuarterState(this);
    }

    public State getPlayingState() {
        return new PlayingState(this);
    }

    public State getPausedState() {
        return new PausedState(this);
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Jukebox jukebox = new Jukebox();
        jukebox.insertQuarter();
        jukebox.pressPlay();
        jukebox.pressPause();
        jukebox.pressPlay();
        jukebox.pressStop();
        jukebox.ejectQuarter();
    }
}

在这个示例中,Jukebox 类是上下文环境类,它维护一个对当前状态对象的引用,并根据状态的变化调用不同的状态类的行为。不同的状态类实现了State接口,并提供了每个状态下具体的行为。


http://www.kler.cn/a/487376.html

相关文章:

  • Google Play开发者账号的高风险行为解析
  • mysql -> 达梦数据迁移(mbp大小写问题兼容)
  • EXCEL: (二) 常用图表
  • 审计表UNIFIED_AUDIT_TRAIL出现YAS-00220 utf8 sequence is wrong
  • 加速物联网HMI革命,基于TouchGFX的高效GUI显示方案
  • android 启动页倒计时页面编写
  • 大模型搜索引擎增强问答demo-纯python实现
  • Sentinel服务保护 + Seata分布式事务
  • 开放词汇检测新晋SOTA:地瓜机器人开源DOSOD实时检测算法
  • C# winform 多线程 UI更新数据 报错:无法访问已释放的对象。
  • 【AI日记】25.01.09
  • 程序血缘分析技术在工商银行软件工程中的应用
  • 一.MySQL程序简介
  • 用BaoStock判断一只股票昨天是否涨停~~
  • GC8872 是一款带故障报告功能的刷式直流电机驱动芯片, 适用于打印机、电器、工业设备以及其他小型机器。
  • 【贵州省】乡镇界arcgis格式shp数据乡镇名称和编码内容下载测评
  • c#学生课程设计之仿windows计算器开发
  • OWASP ZAP安全测试--使用(自动扫描、手动浏览)
  • 系统思考—问题分析
  • 移动端可互动轮播图
  • VoiceBox:基于文本引导的多语种通用大规模语音生成
  • CSS学习记录26
  • 32单片机从入门到精通之软件编程——任务调度(十)
  • 对话新晋 Apache SeaTunnel Committer:张圣航的开源之路与技术洞察
  • Maven核心插件之maven-resources-plugin
  • 如何训练大型语言模型?