State-状态模式
概述:
用类表示状态
说明:
1.本文仅仅是对 图解设计模式 的简单总结(个人笔记).
2.文章中的图片均来自本书,添加水印只是为了防止盗链行为,并无侵权的想法.
综上,若侵权, 请联系我删除!
转载请标注出处!
案例:
- 案例说明:
金库报警系统
- 主要代码:
- 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综述
- 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: 欢迎大家来到我的小站,鸣谢!
猜你喜欢