设计模式 - 状态模式(State)
2017-04-04 17:44
197 查看
State模式允许一个对象在其内部状态改变时改变它的行为。当一个
对象收到其他对象的请求时, 它根据自身的当前状态作出不同的反应。
• 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为;同时对象的行为引起对象的状态的改变。
• 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常, 有多个操作包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
通过 state模式去除复杂的状态改变条件语句。
类图:
案例:地铁闸机状态机
若状态机在lock状态收到一个coin事件,状态改变成unlocked状态并执行unlock动作;
若状态机在unlock状态再收到一个coin事件,状态不变显示”thank you”;
若状态机在unlock状态收到一个pass事件,状态改变成locked状态并执行lock动作;
若状态机在lock状态收到一个pass事件,状态不变并报警。
Step 1: 没有使用State模式,Turnstile对象负责接收事件,TurnstileController负责执行动作。
测试代码:
Step 2: 使用State模式重构去除这些状态改变条件语句。
可以识别出coin()和pass()方法里有状态改变条件语句,定义一个State的接口或抽象超类,将这些方法复制到State的接口或抽象超类 (将上下文类Turnstile传入State中的方法,State的实现类可以调用上下文的方法):
定义实现TurnstileState接口的两个State类:
Step 3: 重构Turnstile,Turnstile称为上下文(context),上下文对象将状态相关的行为委托到状态对象上;上下文对象有一个初始的状态对象。
1) 将状态类型码换成 状态对象
2) coin() 和 pass() 委托给当前的状态对象
通过将Context类中的State变量封装成状态类,状态相关的行为委托到状态对象上,从而去除Context中状态相关的方法中复杂状态改变条件语句。
对象收到其他对象的请求时, 它根据自身的当前状态作出不同的反应。
• 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为;同时对象的行为引起对象的状态的改变。
• 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常, 有多个操作包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
通过 state模式去除复杂的状态改变条件语句。
类图:
案例:地铁闸机状态机
若状态机在lock状态收到一个coin事件,状态改变成unlocked状态并执行unlock动作;
若状态机在unlock状态再收到一个coin事件,状态不变显示”thank you”;
若状态机在unlock状态收到一个pass事件,状态改变成locked状态并执行lock动作;
若状态机在lock状态收到一个pass事件,状态不变并报警。
Step 1: 没有使用State模式,Turnstile对象负责接收事件,TurnstileController负责执行动作。
public class Turnstile { //states public static final int LOCKED = 0; public static final int UNLOCKED = 1; private TurnstileController controller; private int state = LOCKED; public Turnstile(TurnstileController controller) { this.controller = controller; } public void coin() { //coin event if(state == LOCKED) {//状态改变条件语句 state = UNLOCKED; unlock(); } else { thankyou(); } } public void pass() { //pass event if(state == UNLOCKED) {//状态改变条件语句 state = LOCKED; lock(); } else { alarm(); } } public void unlock() { controller.unlock(); } public void lock() { controller.lock(); } public void alarm() { controller.alarm(); } public void thankyou() { controller.thankyou(); } public boolean isLocked() { return state == LOCKED; } public void setLocked() { state = LOCKED; } public boolean isUnlocked() { return state == UNLOCKED; } public void setUnlocked() { state = UNLOCKED; } }
public class TurnstileController { public void unlock() { System.out.println("unlocked turnstile"); } public void thankyou() { System.out.println("thank you"); } public void lock() { System.out.println("Locked turnstile"); } public void alarm () { System.out.println("Can not pass as it is locked"); } }
测试代码:
public class TurnstileTest { @Test public void testTurntileTest() { TurnstileController controller = new TurnstileController(); Turnstile turntile = new Turnstile(controller); assertTrue(turntile.isLocked()); turntile.coin(); assertTrue(turntile.isUnlocked()); turntile.coin(); assertTrue(turntile.isUnlocked()); turntile.pass(); assertTrue(turntile.isLocked()); turntile.pass(); assertTrue(turntile.isLocked()); } }
Step 2: 使用State模式重构去除这些状态改变条件语句。
可以识别出coin()和pass()方法里有状态改变条件语句,定义一个State的接口或抽象超类,将这些方法复制到State的接口或抽象超类 (将上下文类Turnstile传入State中的方法,State的实现类可以调用上下文的方法):
public interface TurnstileState { public void coin(Turnstile turnstile); public void pass(Turnstile turnstile); }
定义实现TurnstileState接口的两个State类:
public class LockedTurntileState implements TurnstileState { public void coin(Turnstile turnstile) { //coin event turnstile.setUnlocked(); turnstile.unlock(); } public void pass(Turnstile turnstile) { //pass event turnstile.alarm(); } }
public class UnlockedTurnstileState implements TurnstileState { public void coin(Turnstile turnstile) { turnstile.thankyou(); } public void pass(Turnstile turnstile) { turnstile.setLocked(); turnstile.lock(); } }
Step 3: 重构Turnstile,Turnstile称为上下文(context),上下文对象将状态相关的行为委托到状态对象上;上下文对象有一个初始的状态对象。
1) 将状态类型码换成 状态对象
2) coin() 和 pass() 委托给当前的状态对象
public class Turnstile { //re b2ac place state types with state objects public static final TurnstileState lockedState = new LockedTurntileState(); public static final TurnstileState unlockedState = new UnlockedTurnstileState(); private TurnstileController controller; private TurnstileState state = lockedState;//初始的状态对象 public Turnstile(TurnstileController controller) { this.controller = controller; } public void coin() { state.coin(this); //delegate state object } public void pass() { state.pass(this); ////delegate state object } public void unlock() { controller.unlock(); } public void lock() { controller.lock(); } public void alarm() { controller.alarm(); } public void thankyou() { controller.thankyou(); } public boolean isLocked() { return state == lockedState; } public void setLocked() { state = lockedState; } public boolean isUnlocked() { return state == unlockedState; } public void setUnlocked() { state = unlockedState; } }
通过将Context类中的State变量封装成状态类,状态相关的行为委托到状态对象上,从而去除Context中状态相关的方法中复杂状态改变条件语句。
相关文章推荐
- 设计模式之State Pattern 状态模式。
- 设计模式学习笔记(二十二)——State状态
- java设计模式-状态模式(STATE)
- 设计模式之(十九)状态模式(state)
- 设计模式--状态模式(State)
- 设计模式(17)-状态模式(State)
- 设计模式之状态(state)模式
- 设计模式学习总结10 - 行为型5 - State状态模式
- 实战设计模式系列-State(状态)
- 设计模式 - State 模式(状态模式)
- [导入]C#面向对象设计模式纵横谈(22):(行为型模式) State 状态模式.zip(6.24 MB)
- 设计模式----State(状态)
- 设计模式——状态模式(State)
- 设计模式----State(状态)模式
- 设计模式--状态模式(State)
- 设计模式之状态模式(State)
- 设计模式----State(状态)
- 设计模式与泡mm的关系之state状态模式及再思考
- 设计模式之State(状态模式)
- 设计模式(19)-状态模式(State)