首页 > 代码库 > 简明 状态模式(5.8)
简明 状态模式(5.8)
当一个类A的某个成员变量的值变化时,可能导致多个行为表现得不同。将该成员变量封装成类型的模式,即为状态模式(state pattern)。
编程技巧:以多态来重构分支结构。
设计思路:解决状态加入、状态转换、状态对行为的影响问题。
状态决定行为
先不考虑状态转换,非常easy看到状态决定行为的场景。“朋友来了有好酒,若是那豺狼来了,迎接它的有猎枪”。
不在状态。该赢的比赛都会输。
例程 4-3 又见分支结构 package property.state; public class Man{ private boolean isHappy;//典型的flag,两种状态 public String sayHello() { String greeting=""; if(isHappy){ greeting ="你好,我的朋友"; }else{ greeting ="好"; } return greeting; } public String sayGoodbye() { return isHappy? "再抱抱!":"再见,再也不见"; } public static void main(String[] args) { Man one = new Man(); one.isHappy =true;//false System.out.println(one.sayHello()); System.out.println(one.sayGoodbye()); } }
这样的Man没有城府,当成员变量isHappy取值不同一时候,Man的sayHello()和sayGoodbye()等多个行为表现得不同。
在简单场景中,if-else更简洁。然而。关键成员变量能够是int或枚举类型表示的好感度。或某个类型如顾客(土豪、凡人、钓丝)。
- 随着状态取值可能性的加入,分支块越来越大。sayHello()和sayGoodbye()代码都变得庞大。
- 特别是添加新的状态值,在分支结构下违反OCP。
从编程技巧上看,状态模式和策略模式、工厂方法模式一样。以多态来重构分支结构。
重构的要点:①以状态类State替代boolean、int、枚举类型或类型(注意这样的情况)的分支推断參数。显然有多少分支。State将相应有多少子类。②状态类State将全部具有上述分支推断的方法,提取为自己的接口,State的子类分别给出配套的实现。例程 4-4 State的子类们 package property.state; public interface State{ public String sayHello(); public String sayGoodbye(); } package property.state; public class FriendState implements State{ @Override public String sayHello(){ return "你好,我的朋友"; } @Override public String sayGoodbye(){ return "再抱抱!"; } }//OpposingState略 package property.state; public class Man2{ private State state; public String sayHello() { return state.sayHello(); } public String sayGoodbye() { return state.sayGoodbye(); } public static void main(String[] args) { Man2 one = new Man2(); one.state =new FriendState();//isHappy = true System.out.println(one.sayHello()); System.out.println(one.sayGoodbye()); } }
在不考虑状态转换时,单纯从代码上看,状态模式的State封装多个方法,而策略模式仅封装一个方法。此时,
状态模式与策略模式的关系,如同抽象工厂与工厂方法的关系。
尽管状态模式封装多个方法,与抽象工厂一样,不会出现[3.2.4方法类型化]的例程3-5那样的组合爆炸,由于多个方法在一个状态下是配套的,而非随意的组合。yqj2065在设计模式学习难度系数排名中。状态模式给的难度系数高达5分(10分制)。
假设不过策略模式基础上的一变多,难度系数应该是1.
在Man的代码中是通过设置isHappy的值改变其状态。在Man2中是通过设置State的对象类型改变其状态。状态之间的变换由外界控制,或者说,多种状态是切割的、无关的。这样的情况下,学习状态模式的难度系数最多是1。
可是,状态模式最有趣的地方正是其状态的变迁。
将涉及一个比較高端的术语Finite State Machine 有限状态机。
2.状态的变迁
.....
简明 状态模式(5.8)