State-状态模式

概述:

用类表示状态

State_sample


说明:

1.本文仅仅是对 图解设计模式 的简单总结(个人笔记).
2.文章中的图片均来自本书,添加水印只是为了防止盗链行为,并无侵权的想法.
综上,若侵权, 请联系删除!
转载请标注出处!


案例:

  • 案例说明:

    金库报警系统

  • State_uml_case
  • 主要代码:
  • SafeFrame.java
    package Gof.State;
    
    import java.awt.Frame;
    import java.awt.Label;
    import java.awt.Color;
    import java.awt.Button;
    import java.awt.TextField;
    import java.awt.TextArea;
    import java.awt.Panel;
    import java.awt.BorderLayout;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    
    public class SafeFrame extends Frame implements ActionListener, Context {
        private TextField textClock = new TextField(60);        // 显示当前时间
        private TextArea textScreen = new TextArea(10, 60);     // 显示警报中心的记录
        private Button buttonUse = new Button("使用金库");      // 金库使用按钮
        private Button buttonAlarm = new Button("按下警铃");    // 按下警铃按钮
        private Button buttonPhone = new Button("正常通话");    // 正常通话按钮
        private Button buttonExit = new Button("结束");         // 结束按钮
    
        private State state = DayState.getInstance();           // 当前的状态
    
        // 构造函数
        public SafeFrame(String title) {
            super(title);
            setBackground(Color.lightGray);
            setLayout(new BorderLayout());
            //  配置textClock
            add(textClock, BorderLayout.NORTH);
            textClock.setEditable(false);
            // 配置textScreen
            add(textScreen, BorderLayout.CENTER);
            textScreen.setEditable(false);
            // 为界面添加按钮
            Panel panel = new Panel();
            panel.add(buttonUse);
            panel.add(buttonAlarm);
            panel.add(buttonPhone);
            panel.add(buttonExit);
            // 配置界面
            add(panel, BorderLayout.SOUTH);
            // 显示
            pack();
            show();
            // 设置监听器
            buttonUse.addActionListener(this);
            buttonAlarm.addActionListener(this);
            buttonPhone.addActionListener(this);
            buttonExit.addActionListener(this);
        }
        // 按钮被按下后该方法会被调用
        public void actionPerformed(ActionEvent e) {
            System.out.println(e.toString());
            if (e.getSource() == buttonUse) {           // 金库使用按钮
                state.doUse(this);
            } else if (e.getSource() == buttonAlarm) {  // 按下警铃按钮
                state.doAlarm(this);
            } else if (e.getSource() == buttonPhone) {  // 正常通话按钮
                state.doPhone(this);
            } else if (e.getSource() == buttonExit) {   // 结束按钮
                System.exit(0);
            } else {
                System.out.println("?");
            }
        }
        // 设置时间
        public void setClock(int hour) {
            String clockstring = "现在时间是";
            if (hour < 10) {
                clockstring += "0" + hour + ":00";
            } else {
                clockstring += hour + ":00";
            }
            System.out.println(clockstring);
            textClock.setText(clockstring);
            state.doClock(this, hour);
        }
        // 改变状态
        public void changeState(State state) {
            System.out.println("从" + this.state + "状態变为了" + state + "状态。");
            this.state = state;
        }
        // 联系警报中心
        public void callSecurityCenter(String msg) {
            textScreen.append("call! " + msg + "\n");
        }
        // 在警报中心留下记录
        public void recordLog(String msg) {
            textScreen.append("record ... " + msg + "\n");
        }
    }
    
  • 时序图:
    uml_sentense
  • 代码链接:传送门

    uml综述State_uml

  • State: 表示状态,定义了根据不同状态进行不同处理的接口(处理内容依赖于状态的方法的集合)
  • ConcreteState: 表示具体的状态,实现了State接口
  • Context: Context角色持有表示当前状态的concreteStatement角色,此外,还定义了供外部调用者使用State模式的接口

收获:

  • 再给表示状态的字段赋予表示当前状态的类的实例,就相当于状态发生改变
  • State表示状态,以此将复杂的程序分解开来
  • Context管理状态迁移,有助于提高contextState独立性,不过这么做context 会知道全部的state,所以可以使用Mediator模式
  • state模式优点:
    • 不会自相矛盾
    • 易于增加新的状态,但在state模式中增加其他”依赖于状态的管理”是否困难的

相关设计模式:

  • singleton: singleton角色会常常出现在concreteState角色中
  • Flyweight: 在表示状态的类中没有定义任何的实例字段,因此,有时我们用Flyweight在多个Context角色之间共享concreteState角色

注意:

此部分内容属于对GOF Design Pattern知识的初步认知阶段,参考书籍是结城浩的《图解设计模式》,简单易懂,十分推荐!
以上内容,作者一字一句码出来的,纯属不易,欢迎大家转载,转载是还请您表明出处。另外如果我有侵权行为,请在下方留言,确认后我会及时撤销相应内容,谢谢大家!

PS: 欢迎大家来到我的小站,鸣谢!