《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

原文地址:https://www.cnblogs.com/draem0507/p/3784943.html