状态模式详解

embedded/2025/1/13 3:34:30/

状态模式详解
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.ppmy.cn/embedded/153449.html

相关文章

Python 基础知识快速过 50题

全篇大概 1000 字(含代码),建议阅读时间 5min 1. 将字符串 ‘a is a’ 改为 ‘b is b’ s a is a s.replace(a, b)什么是转义字符 在字符串中如果含有特殊字符如:单引号、双引号。需要再特殊字符前加 “” 反斜杠才能使用。 3.…

npm发布流程说明

一、进入要发布的项目根目录,初始化为npm包 npm initname:最重要的字段之一,项目名称(少于214个字节)。没有name和version不能进行安装; version:最重要的字段之一,项目版本。没有n…

探索微软 M365 安全:全方位守护数字世界

在当今这个科技呈井喷式飞速发展,数字化浪潮以汹涌澎湃、锐不可当之势席卷全球的时代,企业与个人仿若置身于一片浩瀚无垠、信息奔涌的海洋之中,尽情畅享着技术革新所带来的无穷无尽便利。然而,恰如平静海面下潜藏着暗礁与汹涌暗流,网络安全问题恰似隐匿在暗处、随时可能给…

【2024年华为OD机试】(A卷,100分)- 等和子数组最小和(Java JS PythonC/C++)

一、问题描述 题目描述 给定一个数组nums&#xff0c;将元素分为若干个组&#xff0c;使得每组和相等&#xff0c;求出满足条件的所有分组中&#xff0c;组内元素和的最小值。 输入描述 第一行输入 m 接着输入m个数&#xff0c;表示此数组nums 数据范围&#xff1a;1<m&…

数据通过canal 同步es,存在延迟问题,解决方案

当使用 Canal 同步数据到 Elasticsearch&#xff08;ES&#xff09;时&#xff0c;出现延迟问题通常源于多个因素&#xff0c;如 Canal 配置、网络延迟、ES 的负载和性能瓶颈等。以下是一些解决方案&#xff0c;帮助减少和解决延迟问题&#xff1a; 1. 优化 Canal 配置 Canal…

《OpenCV计算机视觉实战项目》——银行卡号识别

文章目录 项目任务及要求项目实现思路项目实现及代码导入模块设置参数对模版图像中数字的定位处理银行卡的图像处理读取输入图像&#xff0c;预处理找到数字边框使用模版匹配&#xff0c;计算匹配得分 画出并打印结果 项目任务及要求 任务书&#xff1a; 要为某家银行设计一套…

嵌入式C语言:二维数组

目录 一、二维数组的定义 二、内存布局 2.1. 内存布局特点 2.2. 内存布局示例 2.2.1. 数组元素地址 2.2.2. 内存布局图&#xff08;简化表示&#xff09; 2.3. 初始化对内存布局的影响 三、访问二维数组元素 3.1. 常规下标访问方式 3.2. 通过指针访问 3.2.1. 指向数…

C# SQL ASP.NET Web

留学生的课程答疑 按照要求完成程序设计、数据库设计、用户手册等相关技术文档&#xff1b; 要求 1. 计算机相关专业&#xff0c;本科以上学历&#xff0c;至少有1年以上工作经验或实习经历。 2. 熟练掌握WinForm程序开发&#xff0c;或ASP.NET Web编程。 3. 熟悉C#中网络…