前言
本文来自《Head Fist 设计模式》一书的实例,这里仅仅是个人笔记记录
定义
允许对象在内部状态改变是改变它的行为,对象看起来好像修改了他的类
需求
投币出糖果
1.初识状态-待投币
2.持币状态-待转动曲柄
请用状态模式完成
非状态模式Demo
// 使用state状态进行判断处理
public void action_Give_RMB() {
switch (state) {
case STATE_INIT:
System.out.println("看到你投钱了,收到了 1 人民币了");
state = STATE_RMB;
break;
case STATE_RMB:
System.out.println("已投钱状态:已经投钱了,请转动曲柄吧");
break;
case STATE_GUMBALL:
System.out.println("出糖果状态:不要着急,马上有糖");
break;
}
}
开发
建立一个状态接口
接口放2个动作,投币和转动曲柄
package com.sufadi.javatestrundemo;
public interface State {
public void action_Give_RMB();
public void action_turn_Crank();
}
状态独立为类并实现动作接口
初识状态
动作下执行什么样的逻辑都在类修改
package com.sufadi.javatestrundemo;
public class InitState implements State {
private GumballMachine mGumballMachine;
public InitState(GumballMachine mGumballMachine) {
this.mGumballMachine = mGumballMachine;
}
@Override
public void action_Give_RMB() {
System.out.println("看到你投钱了,收到了 1 人民币了");
// 切换下一个状态
mGumballMachine.setState(mGumballMachine.mHasRmbState);
}
@Override
public void action_turn_Crank() {
System.out.println("初识状态:请投钱");
}
}
持币状态
动作下执行什么样的逻辑都在类修改
package com.sufadi.javatestrundemo;
public class HasRmbState implements State {
private GumballMachine mGumballMachine;
public HasRmbState(GumballMachine mGumballMachine) {
this.mGumballMachine = mGumballMachine;
}
@Override
public void action_Give_RMB() {
System.out.println("已投钱状态,不需要额外给糖,转动曲柄吧!");
}
@Override
public void action_turn_Crank() {
System.out.println("接受到转动曲柄动作,出糖并给了你糖果");
// 切换下一个状态
mGumballMachine.setState(mGumballMachine.mInitState);
}
}
糖果机器GumballMachine
将上述的的状态和动作组装在这个糖果
package com.sufadi.javatestrundemo;
public class GumballMachine {
private State mState;
InitState mInitState;
HasRmbState mHasRmbState;
/**
* 装载所有的状态和动作
*/
public GumballMachine() {
mInitState = new InitState(this);
mHasRmbState = new HasRmbState(this);
mState = mInitState;
}
/**
* 便于切换状态
* @param mState
*/
public void setState(State mState) {
this.mState = mState;
}
/**
* 投入金币
*/
public void action_Give_RMB() {
// 状态模式
mState.action_Give_RMB();
}
/**
* 转动手柄
*/
public void action_turn_Crank() {
mState.action_turn_Crank();
}
}
测试程序和测试结果
测试程序
package com.sufadi.javatestrundemo;
public class Test {
public static void main(String[] args) {
GumballMachine machine = new GumballMachine();
machine.action_Give_RMB();
// 多写一句是为了验证程序的出错逻辑是否能正常执行
machine.action_Give_RMB();
machine.action_turn_Crank();
}
}
运行结果
看到你投钱了,收到了 1 人民币了
已投钱状态,不需要额外给糖,转动曲柄吧!
接受到转动曲柄动作,出糖并给了你糖果