《JAVA与模式》之状态模式
在阎宏博士的《JAVA与模式》一书中开头是这样描述状态(State)模式的:
状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式。
状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。
状态模式的结构
用一句话来表述,状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。状态模式的示意性类图如下所示:
状态模式所涉及到的角色有:
● 环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。
● 抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。
● 具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。
状态模式跟策略模式有点像,对比后单纯的从代码结构来看,会发现状态模式多了一个state,这个state是在各个state实现类中的开关
举个例子,风扇有一档,二档和三档,当你按下一档,二档和三档处于可按状态,当你按下二档,一档和三档处于可按状态。好别扭看着,不过说明了他跟策略模式的本质区别
1.策略模式是并行的,而状态模式是互斥的
2.状态模式是内部自己控制的,而策略模式是client控制的(客户端必须知道有多少中策略模式)
1 public class State { 2 3 4 5 public static void main(String[] args) { 6 7 8 /*BadState badState =new BadState(1); 9 badState.say();*/ 10 11 IState state=new BlueState(); 12 ContextState context=new ContextState(state); 13 System.out.println(context.getState().getState()); 14 context.push(); 15 16 System.out.println(context.getState().getState()); 17 } 18 19 } 20 21 /** 22 * 23 * 这个是简单点的情况 24 * 复杂点 加入有三个状态 有1 则下个状态 必然是 2 上个状态是1 ‘ 25 * 状态是2 上一个状态是1 下个状态是 3 26 * 以此类推 27 * 28 * 假如有五个状态以上 估计代码就很难维护了 29 * */ 30 class BadState{ 31 32 33 private int state ; 34 35 public BadState(int state){ 36 37 this.state=state; 38 } 39 40 public void say(){ 41 42 switch (state) { 43 case 1: 44 System.out.println(" hello "); 45 break; 46 case 2: 47 System.out.println(" hi "); 48 break; 49 50 default: 51 break; 52 } 53 54 } 55 56 } 57 58 59 class ContextState { 60 /*** 61 * 红 62 * 蓝 绿 63 * */ 64 65 66 private IState state; 67 68 69 public ContextState (IState state){ 70 this.state =state; 71 72 } 73 74 75 public IState getState() { 76 return state; 77 } 78 79 80 public void setState(IState state) { 81 this.state = state; 82 } 83 84 85 public void push(){ 86 87 state.next(this); 88 89 } 90 public void pull(){ 91 92 state.prev(this); 93 94 } 95 96 97 98 } 99 100 interface IState{ 101 102 public void prev(ContextState c); 103 104 public void next(ContextState c); 105 106 public String getState(); 107 108 } 109 110 /*** 111 * 红 112 * 蓝 绿 113 * */ 114 115 class BlueState implements IState{ 116 117 @Override 118 public void prev(ContextState c) { 119 120 121 c.setState(new RedState()); 122 } 123 124 @Override 125 public void next(ContextState c) { 126 // TODO Auto-generated method stub 127 128 c.setState(new GreenState()); 129 } 130 131 @Override 132 public String getState() { 133 // TODO Auto-generated method stub 134 return "blue"; 135 } 136 } 137 /*** 138 * 红 139 * 蓝 绿 140 * */ 141 142 class GreenState implements IState{ 143 144 @Override 145 public void prev(ContextState c) { 146 147 c.setState(new BlueState()); 148 } 149 150 @Override 151 public void next(ContextState c) { 152 c.setState(new RedState()); 153 154 } 155 156 @Override 157 public String getState() { 158 // TODO Auto-generated method stub 159 return "green"; 160 } 161 } 162 /*** 163 * 红 164 * 蓝 绿 165 * */ 166 167 class RedState implements IState{ 168 169 @Override 170 public void prev(ContextState c) { 171 172 c.setState(new GreenState()); 173 } 174 175 @Override 176 public void next(ContextState c) { 177 c.setState(new BlueState()); 178 179 } 180 181 @Override 182 public String getState() { 183 // TODO Auto-generated method stub 184 return "red"; 185 } 186 }
ps:通过策略模式+工厂模式 可以比较好的解决if else过多的问题 当然这时候 使用策略模式+工厂模式
也是可以的,因为有多少种情况(策略)你肯定知道的
参考:http://www.cnblogs.com/java-my-life/archive/2012/06/08/2538146.html