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 code
return 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 code
return 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();
}
}
运行界面: