• 设计模式之状态模式


    状态模式的定义是:当一个对象内在状态改变时允许其改变行为,这个对象看起来像是改变了自身所属的类。

    该模式适合于对象具有有限的状态,并且在状态之间相互切换。

    例如使用如下的条件分支语句也是属于状态的切换:

    switch (action){  
        case "play":  
            state="playing";  
            break;    
        case "stop":  
            state="stopping";  
            break;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    当后期状态增多和状态转换复杂之后,使用这种方式会对后续的维护增加困难。使用状态模式能有效解决这种维护的困难,通过将与状态相关的行为抽取到独立的状态类中, 让原对象将工作委派给这些类的实例, 而不是自行进行处理,将复杂度隔离在状态类中。

    该模式中存在 3 类对象:

    1. Context 上下文:保持有状态类的引用
    2. State 抽象状态:定义状态的方法
    3. ConcreteState 具体状态
    Context
    - state
    -changeState()
    «interface»
    State
    +action()
    ConcreteState
    +action()

    代码实现:

    //抽象状态
    public abstract class State {  
        protected Player player;  
      
        public State(Player player) {  
            this.player = player;  
        }  
      
        // 停止  
        public abstract void onStop();  
        // 播放  
        public abstract void onPlay();  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    //具体状态:停止状态
    public class StoppingState extends State{  
        public StoppingState(Player player) {  
            super(player);  
        }  
      
        @Override  
        public void onStop() {  
            System.out.println("已经停止");  
        }  
      
        @Override  
        public void onPlay() {  
            player.setState(new PlayingState(player));  
            player.setPlaying(true);  
        }  
    }
    
    // 具体状态:播放状态
    public class PlayingState extends State {  
        public PlayingState(Player player) {  
            super(player);  
        }  
      
        @Override  
        public void onStop() {  
            player.setState(new StoppingState(player));  
            player.setPlaying(false);  
        }  
      
        @Override  
        public void onPlay() {  
            System.out.println("已经在播放");  
        }  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    //上下文对象
    @Data  
    public class Player {  
        private State state;  
        private boolean playing;  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    Player player=new Player();  
    //设置初始状态  
    player.setState(new StoppingState(player));  
    //播放  
    player.getState().onPlay();  
    System.out.println(player.getState());  
    //停止  
    player.getState().onStop();  
    System.out.println(player.getState());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    状态模式的优点是:

    1. 消除了复杂的条件分支语句
    2. 将状态相关的行为封装在状态类中

    缺点是如果状态太少,使用状态模式会显得过于复杂。

  • 相关阅读:
    Misc思路
    项目部署之Jenkins
    AWD学习总结 (会持续更新)
    Oracle 排查慢SQL
    Java中synchronized的优化
    Ubuntu源码编译gdal3.6.2
    走进微软亚洲研究院随笔
    故障009:改写多表关联同时更新且互换列值
    Win10 搭建FTP服务器
    程序设计与算法(三)C++面向对象程序设计笔记 第七周 输入输出和模板
  • 原文地址:https://blog.csdn.net/weixin_54227075/article/details/130911655