JAVA设计模式学习23——状态模式

2019-03-07 14:08|来源: 网络

状态(state)模式:状态模式的意图是,允许一个对象在其内部状改变时改变它的行为。看起来就像是改变了它的类一样。 主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同的一系列类当中,可以把复杂的逻辑判断简单化。    
状态模式的结构如下图:    

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

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-9-3下午10:12:05

  6. *描述:抽象状态类

  7. */  

  8. public interface State {  

  9.  

  10.    public void change(Context context);  

  11.  

  12. }  

Java代码
  1. package state;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-9-3下午10:12:27

  6. *描述:实现状态类

  7. */  

  8. public class ConcreteStateA implements State {  

  9.  

  10.    @Override  

  11.    public void change(Context context) {  

  12.        System.out.println("this is ConcreteStateA");  

  13.        context.setState(new ConcreteStateB());  

  14.    }  

  15. }  

Java代码
  1. package state;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-9-3下午10:13:02

  6. *描述:实现状态类

  7. */  

  8. public class ConcreteStateB implements State {  

  9.  

  10.    @Override  

  11.    public void change(Context context) {  

  12.        System.out.println("this is ConcreteStateB");  

  13.        context.setState(new ConcreteStateA());  

  14.    }  

  15. }  

Java代码
  1. package state;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-9-3下午10:13:20

  6. *描述:环境角色类

  7. */  

  8. public class Context {  

  9.  

  10.    private State state;  

  11.      

  12.    public void change(){  

  13.        state.change(this);  

  14.    }  

  15.      

  16.  

  17.    public Context(State state) {  

  18.        super();  

  19.        this.state = state;  

  20.    }  

  21.  

  22.  

  23.    public State getState() {  

  24.        return state;  

  25.    }  

  26.  

  27.  

  28.    public void setState(State state) {  

  29.        this.state = state;  

  30.    }  

  31.      

  32.      

  33. }  

Java代码
  1. package state;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-9-3下午10:13:37

  6. *描述:测试类

  7. */  

  8. public class Client {  

  9.  

  10.    /**

  11.     *作者:alaric

  12.     *时间:2013-9-3下午7:52:05

  13.     *描述:

  14.     */  

  15.    public static void main(String[] args) {  

  16.          

  17.        State state = new ConcreteStateA();  

  18.        Context context = new Context(state);  

  19.        //初始状态是A  

  20.        context.change();  

  21.        //装换一次后变成B  

  22.        context.change();  

  23.        //再转换一次后又变成A  

  24.        context.change();  

  25.    }  

  26.  

  27. }  



 运行结果如下:    
     this is ConcreteStateA
     this is ConcreteStateB
     this is ConcreteStateA
     上面代码是两个状态切换,很符合家里灯的开关,A表示关,B表示开,按一下打开,再按一下关闭。下面      举个例子,马路上的红绿灯大家都知道的,它有三个状态控制三个不同颜色的灯,我们分别用RedState(红灯状态),GreenState(绿灯状态),YellowState(黄灯状态)表示三个灯的状态,用Light表示灯来模拟,类图如下:
     


模拟代码如下:      

Java代码
  1. package state.example;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-9-7上午11:14:32

  6. *描述:抽象状态类

  7. */  

  8. public interface State {  

  9.  

  10.    public void change(Light light);  

  11. }  

Java代码
  1. package state.example;  

  2.  

  3.  

  4. public class GreenState implements State {  

  5.    private static final Long SLEEP_TIME = 2000L;  

  6.    @Override  

  7.    public void change(Light light) {  

  8.          

  9.        System.out.println("现在是绿灯,可以通行");  

  10.        //绿灯亮1秒  

  11.        try {  

  12.            Thread.sleep(SLEEP_TIME);  

  13.        } catch (InterruptedException e) {  

  14.            // TODO Auto-generated catch block  

  15.            e.printStackTrace();  

  16.        }  

  17.        light.setState(new YellowState());  

  18.    }  

  19.  

  20. }  

Java代码
  1. package state.example;  

  2.  

  3.  

  4. public class YellowState implements State {  

  5.    private static final Long SLEEP_TIME = 500L;  

  6.    @Override  

  7.    public void change(Light light) {  

  8.          

  9.        System.out.println("现在是黄灯,警示");  

  10.        //红灯亮0.5秒  

  11.        try {  

  12.            Thread.sleep(SLEEP_TIME);  

  13.        } catch (InterruptedException e) {  

  14.            // TODO Auto-generated catch block  

  15.            e.printStackTrace();  

  16.        }  

  17.        light.setState(new RedState());  

  18.    }  

  19.  

  20. }  

Java代码
  1. package state.example;  

  2.  

  3.  

  4. public class RedState implements State {  

  5.    private static final Long SLEEP_TIME = 1000L;  

  6.    @Override  

  7.    public void change(Light light) {  

  8.  

  9.        System.out.println("现在是红灯,禁止通行");  

  10.        //红灯亮1秒  

  11.        try {  

  12.            Thread.sleep(SLEEP_TIME);  

  13.        } catch (InterruptedException e) {  

  14.            // TODO Auto-generated catch block  

  15.            e.printStackTrace();  

  16.        }  

  17.        light.setState(new GreenState());  

  18.    }  

  19.  

  20. }  

Java代码
  1. package state.example;  

  2.  

  3. public class Light {  

  4.  

  5.    private State state;  

  6.      

  7.    private void change(){  

  8.        state.change(this);  

  9.    }  

  10.  

  11.    public void work(){  

  12.        while(true){  

  13.            change();  

  14.        }  

  15.    }  

  16.    public Light(State state) {  

  17.        super();  

  18.        this.state = state;  

  19.    }  

  20.  

  21.    public State getState() {  

  22.        return state;  

  23.    }  

  24.  

  25.    public void setState(State state) {  

  26.        this.state = state;  

  27.    }  

  28.      

  29. }  

Java代码
  1. package state.example;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-9-7上午11:27:41

  6. *描述:测试客户端

  7. */  

  8. public class Client {  

  9.  

  10.    /**

  11.     *作者:alaric

  12.     *时间:2013-9-7上午11:27:34

  13.     *描述:

  14.     */  

  15.    public static void main(String[] args) {  

  16.          

  17.        //假设路灯开始是绿灯  

  18.        State state = new GreenState();  

  19.        Light light = new Light(state);  

  20.        light.work();  

  21.                  

  22.    }  

  23.  

  24. }  



运行结果:
现在是绿灯,可以通行      
现在是黄灯,警示      
现在是红灯,禁止通行      
现在是绿灯,可以通行      
现在是黄灯,警示      
现在是红灯,禁止通行      
现在是绿灯,可以通行      
现在是黄灯,警示      
.....      
通过上面例子可以看出,状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来;所有状态相关的代码都存在于某个ConcereteState中,所以通过定义新的子类很容易地增加新的状态和转换;状态模式通过把各种状态转移逻辑分不到State的子类之间,来减少相互间的依赖。缺点是:会导致有很多State 的子类。      
       
状态模式和策略模式结构完全一样,很容易混淆,这里列举下状态模式和策略模式的区别:        
1、状态模式有明显的状态过渡,从一个状态到另一个状态转换过程,在整个生命周期里有多个状态转换;而策略模式一旦环境角色选择了一个具体的策略类,那么在整个生命周期它始终不会改变;        
2、状态模式多数是外在原因在环境角色中放入一个具体的状态类,而策略模式是自主选择一个具体的策略类;        
3、状态模式选择一个状态是会明显告诉客户端的,而策略模式则不会告诉客户端选择了什么策略。        

 
转自:http://alaric.iteye.com/blog/1938400

相关问答

更多
  • 其实我相信你做了3年的java一定了解你所说的设计模式和反射机制在程序早已用过了的把,只是自己平时没注意;设计模式主要是用项目管理,让人看起来通俗易懂.反射机制用到的地方呢也比较多,在用properties和JFreeChart等地方都用到.
  • JAVA23种设计模式[2023-07-15]

    http://www.360doc.com/showRelevantArt.aspx?ArticleID=220068&ArticleNum=92这个网站里面有,去看看..
  • 许多设计模式我们基本用不到,因为有许多都是做底层实现的,比如Iterator模式,用于JDK中做遍历的一个接口Iterator的设计。 我觉得:其实你要掌握的就是 单例、工厂、责任链、动态代理这几个,因为这些设计模式特经典,将面向对象中的 多太、抽象、继承使用的淋漓尽致。。。
  • JAVA23种设计模式[2023-07-01]

    设计模式主要分三个类型:创建型、结构型和行为型。 其中创建型有: 一、Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点 二、Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。 三、Factory Method,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。 四、Builder,建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建 ...
  • JAVA23种设计模式[2022-02-06]

    设计模式主要分三个 类型:创建型、 结构型和行为型。 其中创建型有: 一、Singleton,单例模式:保证一个类只有一个 实例,并提供一个访问它的全局访问点 二、Abstract Factory,抽象工厂:提供一个创建一系列相关或 相互依赖对象的 接口,而无须指定它们的具体类。 三、Factory Method,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。 四、Builder,建造模式:将一个复杂对象的构建与他的表示相分离,使得 ...
  • 设计模式主要分三个 类型:创建型、 结构型和行为型。 其中创建型有: 一、Singleton,单例模式:保证一个类只有一个 实例,并提供一个访问它的全局访问点 二、Abstract Factory,抽象工厂:提供一个创建一系列相关或 相互依赖对象的 接口,而无须指定它们的具体类。 三、Factory Method,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。 四、Builder,建造模式:将一个复杂对象的构建与他的表示相分离,使得 ...
  • 一共23种设计模式! 引用《软件秘笈-设计模式那点事》书籍: 按照目的来分,设计模式可以分为创建型模式、结构型模式和行为型模式。 创建型模式用来处理对象的创建过程;结构型模式用来处理类或者对象的组合;行为型模式用来对类或对象怎样交互和怎样分配职责进行描述。 创建型模式用来处理对象的创建过程,主要包含以下5种设计模式:  工厂方法模式(Factory Method Pattern)  抽象工厂模式(Abstract Factory Pattern)  建造者模式(Builder Pattern)  原 ...
  • 23种设计模式[2021-09-19]

    如何学好Java 学Java请不要做浮躁的人  1.不要看到别人的回复第一句话就说:给个代码吧!你应该想想为什么。当你自己想出来再参考别人的提示,你就知道自己和别人思路的差异。  2.初学者请不要看太多太多的书那会误人子弟的,先找本系统的学,很多人用了很久都是只对部分功能熟悉而已,不系统还是不够的。  3.看帮助,不要因为很难而自己是初学者所以就不看;帮助永远是最好的参考手册,虽然帮助的文字有时候很难看懂,总觉得不够直观。  4.不要被对象、属性、方法等词汇所迷惑;最根本的是先了解最基础知识。  5.不要放 ...
  • 单例模式,工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式) 组合模式,观察者模式,状态模式。这几个应该多了解。
  • 设计模式主要分三个类型:创建型、结构型和行为型。 其中创建型有: 一、Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点 二、Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。 三、Factory Method,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。 四、Builder,建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建 ...