java状态模式

来源:互联网 发布:单片机串口通信程序 编辑:程序博客网 时间:2024/06/02 06:39
第二章节   状态模式
       状态(state)模式:状态模式的意图是,允许一个对象在其内部状改变时改变它的行为。看起来就像是改变了它的类一样。主要解决的是当控制一个对象
状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同的一系列类当中,可以把复杂的逻辑判断简单化。首先咱们还是先看下GOF对状
态模式的定义:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。状态模式中的行为是由状态来决定的,不同的状态对应了不
同的行为。状态模式和策略模式的结构几乎完全一样,但它们的目的、本质却完全不一样。状态模式的行为是平行的不可替换的,策略模式的行为是彼此独立
可相互替换的。
----------------------------------------------------------------------------------------------------------------------------------------------------------
状态模式的结构如下图:

从图中可以看出状态模式有以下角色:
------------------------------------------------------------------------------------
1、抽象状态(State)角色:定义一个接口,用以封装环境对象的一个特定的状态所对应的行为。
2、具体状态(ConcreteState)角色:每一个具体状态类都实现了环境的一个状态所对的行为。
3、场景(Context)角色:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象现有的状态。
上图用代码模拟如下:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
public interface State {  
    public void change(Context context);  
}  

public class ConcreteStateA implements State {  
  
    @Override  
    public void change(Context context) {  
        System.out.println("this is ConcreteStateA");  
        context.setState(new ConcreteStateB());  
    }  
}  

public class ConcreteStateB implements State {  
  
    @Override  
    public void change(Context context) {  
        System.out.println("this is ConcreteStateB");  
        context.setState(new ConcreteStateA());  
    }  
}  

具体的Context 类:
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
package state;  
 
public class Context {  
   
    private State state;  
      
    public void change(){  
        state.change(this);  
    }  
      
  
    public Context(State state) {  
        super();  
        this.state = state;  
    }  
  
  
    public State getState() {  
        return state;  
    }  
  
  
    public void setState(State state) {  
        this.state = state;  
    }  
}  
---------------------------------------------------------------------------------------------------------------------------------------------------
public class Client {  
  
    /** 
     *作者:alaric 
     *时间:2013-9-3下午7:52:05 
     *描述: 
     */  
    public static void main(String[] args) {  
          
        State state = new ConcreteStateA();  
        Context context = new Context(state);  
        //初始状态是A  
        context.change();  
        //装换一次后变成B  
        context.change();  
        //再转换一次后又变成A  
        context.change();  
    }  
}  
运行结果如下:
this is ConcreteStateA
this is ConcreteStateB
this is ConcreteStateA
        上面代码是两个状态切换,很符合家里灯的开关,A表示关,B表示开,按一下打开,再按一下关闭。下面举个例子,马路上的红绿灯大家都知道的,它有三个状态控制三个不同颜色的灯,我们分别用RedState(红灯状态),GreenState(绿灯状态),YellowState(黄灯状态)表示三个灯的状态,用Light表示灯来模拟,类图如下:
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


---------------------------------------------------------------------------------------------------------------------------
状态模式的角色:
(1)上下文环境(Context):它定义了客户程序需要的接口并维护一个具体状态角色的实例,将与状态相关的操作委托
          给当前的Concrete State对象来处理。 
(2)抽象状态角色(State):定义一个接口以封装使用上下文环境的的一个特定状态相关的行为。
(3)具体状态角色(ConcreteState):实现抽象状态定义的接口。
---------------------------------------------------------------------------------------------------------------------------

public interface State { 
    public void change(Light light);  
  //  具体的情况如下所示:
---------------------------------------------------------------------------------------------------------------------------
public class GreenState implements State { 
 
    private static final Long SLEEP_TIME = 2000L;  
    @Override  
    public void change(Light light) {  
          
        System.out.println("现在是绿灯,可以通行");  
        //绿灯亮1秒  
        try {  
            Thread.sleep(SLEEP_TIME);  
        } catch (InterruptedException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        light.setState(new YellowState());  
    }  
  
}  
---------------------------------------------------------------------------------------------------------------------------
public class YellowState implements State {  

    private static final Long SLEEP_TIME = 500L;  
    @Override  
    public void change(Light light) {  
          
        System.out.println("现在是黄灯,警示");  
        //红灯亮0.5秒  
        try {  
            Thread.sleep(SLEEP_TIME);  
        } catch (InterruptedException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        light.setState(new RedState());  
    }  
}  
---------------------------------------------------------------------------------------------------------------------------
public class RedState implements State {  

    private static final Long SLEEP_TIME = 1000L;  
    @Override  
    public void change(Light light) {  
  
        System.out.println("现在是红灯,禁止通行");  
        //红灯亮1秒  
        try {  
            Thread.sleep(SLEEP_TIME);  
        } catch (InterruptedException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        light.setState(new GreenState());  
    }  
}  
------------------------------------------------------------------------------------------------------------------------------
public class Light {  
  
    private State state;  
      
    private void change(){  
        state.change(this);  
    }  
  
    public void work(){  
        while(true){  
            change();  
        }  
    }  

    public Light(State state) {  
        super();  
        this.state = state;  
    }  
  
    public State getState() {  
        return state;  
    }  
  
    public void setState(State state) {  
        this.state = state;  
    }  
      
}  
----------------------------------------------------------------------------------------------------------------------------
public static void main(String[] args) {  
          
        //假设路灯开始是绿灯  
        State state = new GreenState();  
        Light light = new Light(state);  
        light.work();   
    }  
---------------------------------------------------------------------------------------------------------------------------
运行结果:
现在是绿灯,可以通行
现在是黄灯,警示
现在是红灯,禁止通行
现在是绿灯,可以通行
现在是黄灯,警示
现在是红灯,禁止通行
现在是绿灯,可以通行
现在是黄灯,警示
.....
       通过上面例子可以看出,状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来;所有状态相关的代码都存
在于某个ConcereteState中,所以通过定义新的子类很容易地增加新的状态和转换;状态模式通过把各种状态转移逻辑分不到State
的子类之间,来减少相互间的依赖。缺点是:会导致有很多State 的子类。

状态模式和策略模式结构完全一样,很容易混淆,这里列举下状态模式和策略模式的区别:
------------------------------------------------------------------------------------------------------------------------------------------------
1、状态模式有明显的状态过渡,从一个状态到另一个状态转换过程,在整个生命周期里有多个状态转换;而策略模式一旦环境角色选择了
     一个具体的策略类,那么在整个生命周期它始终不会改变;
2、状态模式多数是外在原因在环境角色中放入一个具体的状态类,而策略模式是自主选择一个具体的策略类;
3、状态模式选择一个状态是会明显告诉客户端的,而策略模式则不会告诉客户端选择了什么策略。

0 0
原创粉丝点击