设计模式使用场景实现示例及优缺点(行为型模式——状态模式)

2024-07-19 1109阅读

在一个遥远的国度中,有一个被称为“变幻之城”的神奇城堡。这座城堡有一种特殊的魔法,能够随着王国的需求改变自己的形态和功能。这种神奇的变化是由一个古老的机制控制的,那就是传说中的“状态宝石”。

设计模式使用场景实现示例及优缺点(行为型模式——状态模式)
(图片来源网络,侵删)

在变幻之城中,有四颗宝石,分别代表着不同的状态:和平、战争、丰收和灾难。每当国王决定需要改变城堡的功能时,他就会召集他的四位顾问,每位顾问负责一颗状态宝石。国王会与顾问们讨论当前的国家状况,然后选择一个最适合的状态。

比如,在和平时期,和平宝石会被激活,城堡变成一个庞大的图书馆和学术研究中心,鼓励人们学习和交流知识。而在战争来临时,战争宝石便会发光,城堡则转变为坚不可摧的堡垒,城墙厚重,箭塔林立,保护国民免受侵害。

每次状态的转换都是庄严而神圣的仪式,全城的人都会聚集在城堡广场,见证宝石的力量和城堡的变化。随着时间的推移,这座城堡不仅成为了国家的象征,也成为了人们心中希望和变革的源泉。

然而,真正的挑战来自于灾难宝石的管理。灾难宝石只在最危急的时刻被启用,城堡会转变为避难所和救援中心,为国民提供庇护和援助。但是,灾难宝石的力量非常强大,如果使用不当,可能会带来不可预测的后果。

有一次,当国王生病,无法决策时,一位野心勃勃的顾问擅自启动了灾难宝石,试图借此控制整个王国。城堡开始失控地变形,国民陷入恐慌。幸好,国王及时康复,与其他三位忠诚的顾问一起制止了这场灾难,恢复了城堡的秩序。

状态模式(State Pattern)

状态模式(State Pattern)是一种行为设计模式,它允许一个对象在其内部状态改变时改变它的行为。这种模式通过将状态相关的行为封装在状态对象中,使得当对象的内部状态改变时,其行为也会随之改变,类似于它改变了其类。

核心组件

  • Context(上下文):维护一个指向当前状态对象的引用,并将与状态相关的工作委托给它。
  • State(状态):定义一个接口以封装与上下文的一个特定状态相关的行为。
  • ConcreteState(具体状态):实现状态接口的类,每个类对应一种状态和该状态下的行为。

    适用场景

    1. 对象的行为依赖于它的状态:
      • 对象行为随内部状态改变而改变时,可以使用状态模式而不是在对象操作中使用大量的条件分支。
      • 业务逻辑包含大量与对象状态有关的条件语句:
        • 当一个操作中包含巨大的多分支条件转移语句,且这些分支依赖于对象状态时,状态模式可以将分支处理移动到它们各自的状态类中。

    实现实例

    以音乐播放器的播放、暂停、停止等状态转换为例,通过状态模式管理状态改变带来的行为改变。

    状态接口(State Interface)

    定义了状态相关行为的方法。

    public interface State {
        void doAction(Context context); // 执行与状态相关的行为,并更新上下文的状态
    }
    

    具体状态(Concrete State)

    实现不同状态下的具体行为。

    PlayingState
    public class PlayingState implements State {
        public void doAction(Context context) {
            System.out.println("Music is playing"); // 执行播放音乐的行为
            context.setState(this); // 更新上下文的状态
        }
        public String toString(){
            return "Playing State"; // 返回状态信息
        }
    }
    
    PausedState
    public class PausedState implements State {
        public void doAction(Context context) {
            System.out.println("Music is paused"); // 执行暂停音乐的行为
            context.setState(this); // 更新上下文的状态
        }
        public String toString(){
            return "Paused State"; // 返回状态信息
        }
    }
    
    StoppedState
    public class StoppedState implements State {
        public void doAction(Context context) {
            System.out.println("Music is stopped"); // 执行停止音乐的行为
            context.setState(this); // 更新上下文的状态
        }
        public String toString(){
            return "Stopped State"; // 返回状态信息
        }
    }
    

    上下文(Context)

    管理和委托给当前状态对象的类。

    public class MusicPlayerContext {
        private State state; // 当前状态对象
        public MusicPlayerContext(){
            state = null; // 初始化状态为空
        }
        public void setState(State state){
            this.state = state; // 设置当前状态
        }
        public State getState(){
            return state; // 获取当前状态
        }
    }
    

    客户端代码(Client Code)

    演示状态模式的使用。

    public class Client {
        public static void main(String[] args) {
            MusicPlayerContext context = new MusicPlayerContext(); // 创建上下文对象
            State playing = new PlayingState(); // 创建播放状态对象
            playing.doAction(context); // 执行播放音乐的行为并更新状态
            System.out.println(context.getState().toString()); // 输出当前状态信息
            State paused = new PausedState(); // 创建暂停状态对象
            paused.doAction(context); // 执行暂停音乐的行为并更新状态
            System.out.println(context.getState().toString()); // 输出当前状态信息
            State stopped = new StoppedState(); // 创建停止状态对象
            stopped.doAction(context); // 执行停止音乐的行为并更新状态
            System.out.println(context.getState().toString()); // 输出当前状态信息
        }
    }
    

    解释

    • 状态接口(State Interface):定义了 doAction(Context context) 方法,所有具体状态类都必须实现这个方法。
    • 具体状态(Concrete State):实现 State 接口,定义了在特定状态下的具体行为。PlayingState、PausedState 和 StoppedState 分别定义了播放、暂停和停止音乐的行为。
    • 上下文(Context):MusicPlayerContext 类保存了当前状态对象,并提供了设置和获取当前状态的方法。
    • 客户端代码(Client Code):客户端代码创建具体的状态和上下文对象,并通过执行行为和更新状态来模拟音乐播放器的状态转换。

      这种设计模式的优势在于将与状态相关的行为局部化,并且将特定状态的行为分配到代表该状态的类中。这样做可以避免代码中的大量条件语句,并使得系统更易于理解和维护。

      优缺点

      优点
      1. 封装状态转换规则:
        • 状态模式将所有与某个状态相关的行为都封装在一个类中,也可以在类内部维护状态转换的逻辑。
        • 增加新的状态简单:
          • 添加新状态只需增加一个新的具体状态类,无需修改现有的代码,符合开闭原则。
      缺点
      1. 增加对象数量:
        • 每个状态都需要一个具体的类,随着状态数量增加,系统中类的个数也会增多。

      类图

      +----------------+         +---------------+         +-----------------+
      |    Context     ||     State     |
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]