设计模式笔记 ------ 状态模式

  现在的面向对象软件开发过程中,对象便是核心。而对象在不同的情况下会表现出不同的行为,这便是状态。我们也许会用一堆 if-else 判断,或者 switch-case 状态机,但在复杂的状态情况下,状态模式应运而生。

状态模式:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

  结构类图如下

  上图中包括:

  1、环境类(Context): 定义客户感兴趣的接口。维护一个ConcreteState子类的实例,这个实例定义当前状态。

  2、抽象状态类(AbstractState): 定义一个接口以封装与Context的一个特定状态相关的行为。

  3、具体状态类(ConcreteState): 每一子类实现一个与Context的一个状态相关的行为。

  

  下面看个例子:假设现在有一个开关,控制三种颜色的切换,blue,green,red,蓝色下一个绿色,绿色下一个红色,红色下一个是蓝色,也可以倒过来。

  首先是抽象状态类

/* 
 * 抽象状态类,执行上一个下一个的操作,还可以获得当前的状态 
 * 当然在这可以既执行别的操作,比如开关拨到某个颜色的时候,颜色对应的灯亮 
 */  
  
public interface State {  
  
    public  void last(Context c);  
  
    public  void next(Context c);  
      
    public  String getState();  
  
  
}  

   其次是具体状态类

/* 
 * 蓝色状态类,实现的接口的方法,通过状态管理器在上一个或者下一个方法中 
 * 设置改变后的状态 
 */  
public class BlueState implements State {  
  
    public String getState() {  
        // TODO Auto-generated method stub  
        return "blue";  
    }  
  
    public void last(Context c) {  
        c.setState(new GreenState());  
  
    }  
  
    public void next(Context c) {  
        c.setState(new RedState());  
  
    }  
  
}  
/* 
 * 绿色状态类,实现的接口的方法,通过状态管理器在上一个或者下一个方法中 
 * 设置改变后的状态 
 */  
public class GreenState implements State {  
  
    public String getState() {  
          
        return "green";  
    }  
  
    public void last(Context c) {  
        c.setState(new RedState());  
  
    }  
  
    public void next(Context c) {  
    c.setState(new BlueState());  
  
    }  
  
}  
/* 
 * 红色状态类,实现的接口的方法,通过状态管理器在上一个或者下一个方法中 
 * 设置改变后的状态 
 */  
 public class RedState implements State {  
  
public String getState() {  
    return "red";  
}  
  
public void last(Context c) {  
c.setState(new BlueState());  
  
}  
  
public void next(Context c) {  
    c.setState(new GreenState());  
  
}  

   最后是环境类

/* 
 * 环境类,设置初始状态,得到当前状态, 
 * 提供了两个操作,上一个的操作方法中,调用了当前状态的last方法,将状态管理器的状态更新 
 *                下一个的操作方法中,调用了当前状态的next方法,将状态管理器的状态更新 
 */  
public class Context {  
      
    private State state = null;  
  
    public State getState() {  
        return state;  
    }  
  
    public void setState(State state) {  
        this.state = state;  
    }  
      
    public void push(){  
          
        state.last(this);  
        System.out.println(state.getState());  
    }  
      
    public void pull(){  
          
        state.next(this);  
        System.out.println(state.getState());  
    }  
      
  
}  

   测试类

/* 
 * 测试类 
 */  
public class Client{  
  
    public static void main(String[] args) throws InterruptedException {  
        /* 
         * 创建一个状态管理器,设置初始状态为红色, 
         * 然后就可以执行状态管理器的last或者next方法 
         */  
        Context c = new Context();  
        State redsState = new RedState();         
        c.setState(redsState);  
            while (true){  
                System.out.println("当前状态:"+c.getState().getState());  
                System.out.print("上一个状态: ");  
                 c.push();  
                 Thread.currentThread().sleep(2000);  
            }          
    }  
      
}  

 结果为

  从上面的例子可以看出一些状态模式的优缺点:

  优点:

1、它将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
2、它使得状态转换显式化。
3、State对象可被共享。

  缺点:

1、状态模式的使用必然会增加系统类和对象的个数。
2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。

 

  总结:状态模式的主要优点在于封装了转换规则,并枚举可能的状态,它将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为,还可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数;其缺点在于使用状态模式会增加系统类和对象的个数,且状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱,对于可以切换状态的状态模式不满足“开闭原则”的要求。

posted @ 2017-06-23 11:32  Adam_Jin  阅读(152)  评论(0编辑  收藏  举报