状态模式

状态模式:当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。类图如下:

                
抽象状态角色(State):

  接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换。以手机为例:

1 public interface ICellState{
2     public float NORMAL_LIMIT=0;//正常状态
3     public float STOP_LIMIT=-1;//停机状态
4     public float COST_MINUTE=0.20f;//话费标准
5     public boolean phone(CellContext ct);
6 }

具体状态角色(ConcreteState):

  每个具体状态必须完成两个责任--本状态的行为管理以及趋向状态处理。给出三种状态分别是正常、透支、停机状态

正常状态:

1 public class NormalState implements ICellState{
2     @Override
3     public boolean phone(CellContext ct) {
4         int min = (int)(Math.random()*10+1);//打电话用时随机
5         ct.cost(min);
6         return false;
7     }
8 }

透支状态:

1 public class OverDrawState implements ICellState{
2     @Override
3     public boolean phone(CellContext ct) {
4         System.out.println("话费已透支!");
5         int min = (int)(Math.random()*10+1);//打电话用时随机
6         ct.cost(min);
7         return false;
8     }
9 }

停机状态:

1 public class StopState implements ICellState{
2     @Override
3     public boolean phone(CellContext ct) {
4         return false;
5     }
6 }

环境角色(Context):

  定义客户端需要的接口,并且负责具体的状态的切换。

 1 public class CellContext{
 2     private String strPhone;
 3     private String name;
 4     private float price;
 5     public ICellState state = null;
 6     public CellContext(String strPhone, String name, float price) {
 7         super();
 8         this.strPhone = strPhone;
 9         this.name = name;
10         this.price = price;
11     }
12     public void save(float price){
13         this.price += price;
14     }
15     public void cost(int minute){
16         this.price -= ICellState.COST_MINUTE*minute;
17     }
18     public boolean call(){
19         if(price>ICellState.NORMAL_LIMIT){
20             state = new NormalState();
21         }else if (price<ICellState.STOP_LIMIT) {
22             state = new StopState();
23         }else {
24             state = new OverDrawState();
25         }
26         state.phone(this);
27         return true;
28     }
29 }

 

 客户端代码:

1 public class Client{
2     public static void main(String[] args) {
3         CellContext c = new CellContext("15012345678","Tom",1);
4         c.call();
5         c.save(1.1);
6         c.call();
7     }
8 }

结果就是CellContext的对象c动态的切换状态,而行为也随之变化。

总结:

  状态模式的本质就是根据状态来分离和选择行为。

  如果一个对象的行为取决于他的状态,而且它必须在运行期根据状态来改变它的行为,可以使用状态模式。

  状态模式体现了开闭原则并且具有良好的封装性,但是可能会有太多的小的状态类造成复杂度增加。

posted @ 2017-06-04 17:10  夏虫语冰、  阅读(128)  评论(0编辑  收藏  举报