📄 r_state.java
字号:
/*
STATE—跟MM交往时,一定要注意她的状态哦,在不同的状态时她的行为会有不同,比如你约她今天晚上去看电影,对你没兴趣的MM就会说“有事情啦”,对你不讨厌但还没喜欢上的MM就会说“好啊,不过可以带上我同事么?”,已经喜欢上你的MM就会说“几点钟?看完电影再去泡吧怎么样?”,当然你看电影过程中表现良好的话,也可以把MM的状态从不讨厌不喜欢变成喜欢哦。
状态模式:状态模式允许一个对象在其内部状态改变的时候改变行为。这个对象看上去象是改变了它的类一样。状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。状态模式需要对每一个系统可能取得的状态创立一个状态类的子类。当系统的状态变化时,系统便改变所选的子类。
状态模式在工作流或游戏等各种系统中有大量使用,甚至是这些系统的核心功能设计,例如政府OA中,一个批文的状态有多种:未办;正在办理;正在批示;正在审核;已经完成等各种状态,使用状态机可以封装这个状态的变化规则,从而达到扩充状态时,不必涉及到状态的使用者。
在网络游戏中,一个游戏活动存在开始;开玩;正在玩;输赢等各种状态,使用状态模式就可以实现游戏状态的总控,而游戏状态决定了游戏的各个方面,使用状态模式可以对整个游戏架构功能实现起到决定的主导作用。
状态模式实质:
使用状态模式前,客户端外界需要介入改变状态,而状态改变的实现是琐碎或复杂的。
使用状态模式后,客户端外界可以直接使用事件Event实现,根本不必关心该事件导致如何状态变化,这些是由状态机等内部实现。
这是一种Event-condition-State,状态模式封装了condition-State部分。
每个状态形成一个子类,每个状态只关心它的下一个可能状态,从而无形中形成了状态转换的规则。如果新的状态加入,只涉及它的前一个状态修改和定义。
*/
import java.awt.*;
import java.awt.event.*;
public class R_State{
public static void main(String args[]){
SafeFrame frame = new SafeFrame("State Sample");
while (true) {
for (int hour = 0; hour < 24; hour++) {
frame.setClock(hour); // 设定时间
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}
}
interface Context {
public abstract void setClock(int hour); // 设定时间
public abstract void changeState(State state); // 状态变化
public abstract void callSecurityCenter(String msg); // 呼叫保安中心
public abstract void recordLog(String msg); // 保安中心保留记录
}
interface State {
public abstract void doClock(Context context, int hour); // 设定时间
public abstract void doUse(Context context); // 使用金库
public abstract void doAlarm(Context context); // 警铃
public abstract void doPhone(Context context); // 一般通话
}
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);
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");
}
}
class NightState implements State {
private static NightState singleton = new NightState();
private NightState() { // 构造子为private
}
public static State getInstance() { // 取得唯一的实例
return singleton;
}
public void doClock(Context context, int hour) { // 设定时间
if (9 <= hour && hour < 17) {
context.changeState(DayState.getInstance());
}
}
public void doUse(Context context) { // 使用金库
context.callSecurityCenter("异常:晚间使用金库!");
}
public void doAlarm(Context context) { // 警铃
context.callSecurityCenter("警铃(晚间)");
}
public void doPhone(Context context) { // 一般通话
context.recordLog("晚间的通话录音");
}
public String toString() { // 输出字串
return "[晚间]";
}
}
class DayState implements State {
private static DayState singleton = new DayState();
private DayState() { // 构造子为private
}
public static State getInstance() { // 取得唯一的实例
return singleton;
}
public void doClock(Context context, int hour) { // 设定时间
if (hour < 9 || 17 <= hour) {
context.changeState(NightState.getInstance());
}
}
public void doUse(Context context) { // 使用金库
context.recordLog("使用金库(白天)");
}
public void doAlarm(Context context) { // 警铃
context.callSecurityCenter("警铃(白天)");
}
public void doPhone(Context context) { // 一般通话
context.callSecurityCenter("一般的通话(白天)");
}
public String toString() { // 输出字串
return "[白天]";
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -