读书笔记_java设计模式深入研究 第八章 状态模式 State
1,状态模式:事务有n个状态,且维护状态变化。
![]()
![]()
![]()
![]()
2,UML模型:
-1,上下文环境Context:定义客户程序需要的接口并维护一个具体状态角色的实例,将与状态相关的操作委托给当前的Concrete State对象来处理。
-2,抽象状态State:定义接口以封装上下文环境的一个特定状态的行为。
-3,具体状态ConcreteState:具体状态。
3,简单代码:
package pattern.chp08.state.simple;/*** 类描述:状态抽象接口** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 10:44:21 AM Jing Created.**/public interface IState {/**** 方法说明:状态更改** Author: Jing* Create Date: Dec 26, 2014 10:44:44 AM** @return void*/void goState();}
package pattern.chp08.state.simple;/*** 类描述:状态B** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 10:50:24 AM Jing Created.**/public class ConcreteStateB implements IState{public void goState() {System.out.println("ConcreteStateB");}}
package pattern.chp08.state.simple;/*** 类描述:状态A** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 10:50:04 AM Jing Created.**/public class ConcreteStateA implements IState {public void goState() {System.out.println("ConcreteStateA");}}
package pattern.chp08.state.simple;/*** 类描述:上下文** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 10:52:03 AM Jing Created.**/public class Context {private IState state;public void setState(IState state) {this.state = state;}/**** 方法说明:根据条件选择某种状态** Author: Jing* Create Date: Dec 26, 2014 10:52:51 AM** @return void*/public void manage(){state.goState();}}
4,深入理解状态模式
-1,利用上下文类控制状态
手机应用,假设手机功能有存款和打电话,状态有正常、透支、停机。使用状态模式模拟:
package pattern.chp08.state.cellState;/*** 类描述:手机状态接口** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 11:04:09 AM Jing Created.**/public interface ICellState {/*** 正常状态*/public float NORMAL_LIMIT = 0;/*** 停机状态*/public float STOP_LIMIT = -1;/*** 话费标准*/public float COST_MINUTE = 0.20F;/**** 方法说明:电话** Author: Jing* Create Date: Dec 26, 2014 11:21:01 AM** @param ct* @return* @return boolean*/boolean phone(CellContext ct);}
package pattern.chp08.state.cellState;/*** 类描述:正常状态** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 11:35:54 AM Jing Created.**/public class NormalState implements ICellState {public boolean phone(CellContext ct) {System.out.println(ct.name + ": 处于正常状态");int minute = (int) (Math.random() * 10 + 1);// 随机产生打电话分钟数ct.cost(minute);//some save codereturn false;}}
package pattern.chp08.state.cellState;/*** 类描述:透支状态下电话类** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 11:36:47 AM Jing Created.**/public class OverDrawState implements ICellState {public boolean phone(CellContext ct) {System.out.println(ct.name + ": 处于透支状态");int minute = (int) (Math.random() * 10 + 1);// 随机产生打电话分钟数ct.cost(minute);//some save codereturn false;}}
package pattern.chp08.state.cellState;/*** 类描述:停机状态** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 11:36:23 AM Jing Created.**/public class StopState implements ICellState {public boolean phone(CellContext ct) {System.out.println(ct.name + ": 处于停机状态");return false;}}
package pattern.chp08.state.cellState;/*** 类描述:手机上下文状态类** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 11:30:09 AM Jing Created.**/public class CellContext {String strPhone;// 电话号码String name;// 姓名float price;// 金额public CellContext(String strPhone, String name, float price) {this.strPhone = strPhone;this.name = name;this.price = price;}/**** 方法说明:手机存钱** Author: Jing* Create Date: Dec 26, 2014 11:31:41 AM** @param price* @return void*/public void save(float price){this.price += price;}/**** 方法说明:手机话费** Author: Jing* Create Date: Dec 26, 2014 11:32:13 AM** @param minute* @return void*/public void cost(int minute){this.price -= ICellState.COST_MINUTE * minute;}/**** 方法说明:获取不同手机状态** Author: Jing* Create Date: Dec 26, 2014 11:33:15 AM** @return* @return boolean*/public boolean call(){ICellState state = null;if(price > ICellState.NORMAL_LIMIT){state = new NormalState();}else if(price < ICellState.STOP_LIMIT){state = new StopState();}else{state = new OverDrawState();}state.phone(this);return true;}}
/*** 类描述:** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 2:25:14 PM Jing Created.**/public class Test {public static void main(String[] args) {CellContext c = new CellContext("213130", "LaoLiu", 1);c.call();c.call();}}
5,应用探索
计算机内存监控
package pattern.chp08.state.ctrl;import java.awt.Container;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JComponent;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JTextField;/*** 类描述:参数控制面板** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 2:35:38 PM Jing Created.**/public class CtrlPanel extends JPanel {private static final long serialVersionUID = -6539318368246202726L;JComponent[] c = { new JTextField(4), new JTextField(4), new JButton("开始检测"),new JButton("停止检测") };boolean bmark[][] = { { true, true, true, false }, { false, false, false, true } };ActionListener startAct = new ActionListener() {// 开始检测 按钮响应事件public void actionPerformed(ActionEvent e) {setState(1);// 设置组件为初始状态int high = Integer.parseInt(((JTextField) c[0]).getText());int low = Integer.parseInt(((JTextField) c[1]).getText());Container c = CtrlPanel.this.getParent();String className = c.getClass().getName();while (!"pattern.chp08.state.ctrl.MyFrame".equalsIgnoreCase(className)) {c = c.getParent();className = c.getClass().getName();}((MyFrame) c).startMonitor(high, low);}};ActionListener stopAct = new ActionListener() {// 停止检测 按钮响应public void actionPerformed(ActionEvent e) {setState(0);Container c = CtrlPanel.this.getParent();String className = c.getClass().getName();while (!"pattern.chp08.state.ctrl.MyFrame".equalsIgnoreCase(className)) {c = c.getParent();className = c.getClass().getName();}((MyFrame) c).stopMonitor();}};public CtrlPanel() {add(new JLabel("优良"));add(c[0]);add(new JLabel("良好"));add(c[1]);add(c[2]);add(c[3]);setState(0);// 设置初始((JButton) c[2]).addActionListener(startAct);((JButton) c[3]).addActionListener(stopAct);}/**** 方法说明:设置按钮状态** Author: Jing Create Date: Dec 26, 2014 2:42:17 PM** @param nState* @return void*/void setState(int nState) {for (int i = 0; i < bmark[nState].length; i++) {c[i].setEnabled(bmark[nState][i]);}}}
package pattern.chp08.state.ctrl;import javax.swing.Box;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JTextField;import javax.swing.border.BevelBorder;/*** 类描述:中间数值展示面板类** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 3:02:21 PM Jing Created.**/public class ContentPanel extends JPanel {private static final long serialVersionUID = 3347768107958337339L;JTextField totalField = new JTextField(20);//总内存展示JTextField freeField = new JTextField(20);//空闲内存显示JTextField ratioField = new JTextField(20);//空闲率展示@SuppressWarnings("static-access")public ContentPanel() {totalField.setEditable(false);freeField.setEditable(false);ratioField.setEditable(false);Box b1 = Box.createVerticalBox();b1.add(new JLabel("总内存:"));b1.add(b1.createVerticalStrut(16));b1.add(new JLabel("空闲内存:"));b1.add(b1.createVerticalStrut(16));b1.add(new JLabel("所占比例:"));b1.add(b1.createVerticalStrut(16));Box b2 = Box.createVerticalBox();b2.add(totalField);b2.add(b2.createVerticalStrut(16));b2.add(freeField);b2.add(b2.createVerticalStrut(16));b2.add(ratioField);b2.add(b2.createVerticalStrut(16));add(b1);add(b2);setBorder(new BevelBorder(BevelBorder.RAISED));}/**** 方法说明:设置对应Field值** Author: Jing* Create Date: Dec 26, 2014 3:11:22 PM** @param value* @param free* @param ratio* @return void*/void setValue(long value, long free, long ratio){totalField.setText(value + " M");freeField.setText(free + " M");ratioField.setText(ratio + "%");}}
package pattern.chp08.state.ctrl;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JTextField;/*** 类描述:上下文类** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 3:24:15 PM Jing Created.**/public class StatePanel extends JPanel {private static final long serialVersionUID = 1L;JTextField txtInfo = new JTextField(4);JTextField txtHour = new JTextField(10);IState state;int mark = -1;public StatePanel() {add(new JLabel("当前内存状态: "));add(txtInfo);add(new JLabel("持续时间: "));add(txtHour);txtInfo.setEnabled(false);txtHour.setEnabled(false);}/** 设置内存状态*/public void setState(int mark) {if (this.mark == mark) {// 内存无变化return;}this.mark = mark;switch (mark) {case 1:state = new HighState();break;case 2:state = new MidState();break;case 3:state = new LowState();break;}}/**** 方法说明:设置对应值** Author: Jing Create Date: Dec 26, 2014 3:31:39 PM** @return void*/public void process() {txtInfo.setText(state.getStateInfo());int size = state.getStateInterval();//DecimalFormat df = new DecimalFormat("0.00");txtHour.setText("" + /*df.format((float) size / 3600)*/ size + " S");}}
package pattern.chp08.state.ctrl;/*** 类描述:状态接口** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 3:17:18 PM Jing Created.**/public interface IState {/**** 方法说明:获取状态信息** Author: Jing Create Date: Dec 26, 2014 3:17:45 PM** @return* @return String*/String getStateInfo();/**** 方法说明:获取统计频率** Author: Jing Create Date: Dec 26, 2014 3:18:12 PM** @return* @return int*/int getStateInterval();}
package pattern.chp08.state.ctrl;/*** 类描述:内存紧张** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 3:19:28 PM Jing Created.**/public class LowState implements IState {private int times;public String getStateInfo() {//some other code//此处可设置通知管理员等其他代码return "一般";}public int getStateInterval() {return times++;}}
package pattern.chp08.state.ctrl;/*** 类描述:内存充足** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 3:18:56 PM Jing Created.**/public class HighState implements IState {private int times;public String getStateInfo() {//some other code//此处可设置通知管理员等其他代码return "充足";}public int getStateInterval() {return times++;}}
package pattern.chp08.state.ctrl;/*** 类描述:内存良好** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 3:19:12 PM Jing Created.**/public class MidState implements IState {private int times;public String getStateInfo() {//some other code//此处可设置通知管理员等其他代码return "良好";}public int getStateInterval() {return times++;}}
package pattern.chp08.state.ctrl;import java.awt.BorderLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JFrame;import javax.swing.Timer;import sun.management.ManagementFactory;import com.sun.management.OperatingSystemMXBean;/*** 类描述:主窗口** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 3:47:44 PM Jing Created.**/public class MyFrame extends JFrame implements ActionListener {private static final long serialVersionUID = 1L;CtrlPanel ctrlPanel = new CtrlPanel();// 参数面板ContentPanel contentPanel = new ContentPanel();// 数值显示面板StatePanel statePanel = new StatePanel();// 状态面板Timer timer = new Timer(1000, this);// 定时器int high, mid;/**** 方法说明:初始化** Author: Jing Create Date: Dec 26, 2014 3:51:54 PM** @return void*/public void init() {add(ctrlPanel, BorderLayout.NORTH);add(contentPanel, BorderLayout.CENTER);add(statePanel, BorderLayout.SOUTH);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setSize(500, 220);setVisible(true);}/**** 方法说明:启动自动检测** Author: Jing Create Date: Dec 26, 2014 3:53:53 PM** @param high* @param mid* @return void*/public void startMonitor(int high, int mid) {this.high = high;this.mid = mid;timer.start();}/**** 方法说明:停止检测** Author: Jing Create Date: Dec 26, 2014 3:54:51 PM** @return void*/public void stopMonitor() {timer.stop();}public void actionPerformed(ActionEvent e) {// 定时器响应方法OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();long total = osmxb.getTotalPhysicalMemorySize();long free = osmxb.getFreePhysicalMemorySize();int ratio = (int) (free * 100L / total);contentPanel.setValue(total / (1024 * 1024), free / (1024 * 1024), ratio);int mark = -1;if (ratio >= high) {mark = 1;} else if (ratio < mid) {mark = 3;} else {mark = 2;}statePanel.setState(mark);statePanel.process();}}
package pattern.chp08.state.ctrl;/*** 类描述:** @author: Jing* @version $Id: Exp$** History: Dec 26, 2014 4:02:27 PM Jing Created.**/public class Test {public static void main(String[] args) {new MyFrame().init();}}
运行界面:
欢迎转载,但转载请注明原文链接[博客园: http://www.cnblogs.com/jingLongJun/]
[CSDN博客:http://blog.csdn.net/mergades]。
如相关博文涉及到版权问题,请联系本人。
[CSDN博客:http://blog.csdn.net/mergades]。
如相关博文涉及到版权问题,请联系本人。

浙公网安备 33010602011771号