状态(state)模式:状态模式的意图是,允许一个对象在其内部状改变时改变它的行为。看起来就像是改变了它的类一样。主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同的一系列类当中,可以把复杂的逻辑判断简单化。
状态模式的结构如下图:
从图中可以看出状态模式有以下角色:
1、抽象状态(State)角色:定义一个接口,用以封装环境对象的一个特定的状态所对应的行为。
2、具体状态(ConcreteState)角色:每一个具体状态类都实现了环境的一个状态所对的行为。
3、场景(Context)角色:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象现有的状态。
上图用代码模拟如下:
package state; /** * *作者:alaric *时间:2013-9-3下午10:12:05 *描述:抽象状态类 */ public interface State { public void change(Context context); }
package state; /** * *作者:alaric *时间:2013-9-3下午10:12:27 *描述:实现状态类 */ public class ConcreteStateA implements State { @Override public void change(Context context) { System.out.println("this is ConcreteStateA"); context.setState(new ConcreteStateB()); } }
package state; /** * *作者:alaric *时间:2013-9-3下午10:13:02 *描述:实现状态类 */ public class ConcreteStateB implements State { @Override public void change(Context context) { System.out.println("this is ConcreteStateB"); context.setState(new ConcreteStateA()); } }
package state; /** * *作者:alaric *时间:2013-9-3下午10:13:20 *描述:环境角色类 */ 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; } }
package state; /** * *作者:alaric *时间:2013-9-3下午10:13:37 *描述:测试类 */ 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表示灯来模拟,类图如下:
模拟代码如下:
package state.example; /** * *作者:alaric *时间:2013-9-7上午11:14:32 *描述:抽象状态类 */ public interface State { public void change(Light light); }
package state.example; 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()); } }
package state.example; 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()); } }
package state.example; 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()); } }
package state.example; 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; } }
package state.example; /** * *作者:alaric *时间:2013-9-7上午11:27:41 *描述:测试客户端 */ public class Client { /** *作者:alaric *时间:2013-9-7上午11:27:34 *描述: */ public static void main(String[] args) { //假设路灯开始是绿灯 State state = new GreenState(); Light light = new Light(state); light.work(); } }运行结果:
现在是绿灯,可以通行
现在是黄灯,警示
现在是红灯,禁止通行
现在是绿灯,可以通行
现在是黄灯,警示
现在是红灯,禁止通行
现在是绿灯,可以通行
现在是黄灯,警示
.....
通过上面例子可以看出,状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来;所有状态相关的代码都存在于某个ConcereteState中,所以通过定义新的子类很容易地增加新的状态和转换;状态模式通过把各种状态转移逻辑分不到State的子类之间,来减少相互间的依赖。缺点是:会导致有很多State 的子类。
状态模式和策略模式结构完全一样,很容易混淆,这里列举下状态模式和策略模式的区别:
1、状态模式有明显的状态过渡,从一个状态到另一个状态转换过程,在整个生命周期里有多个状态转换;而策略模式一旦环境角色选择了一个具体的策略类,那么在整个生命周期它始终不会改变;
2、状态模式多数是外在原因在环境角色中放入一个具体的状态类,而策略模式是自主选择一个具体的策略类;
3、状态模式选择一个状态是会明显告诉客户端的,而策略模式则不会告诉客户端选择了什么策略。
设计模式系列目录:
相关推荐
以上只是部分Java设计模式的介绍,实际的“DesignPatterns”压缩包可能包含了这些模式的源代码实现,通过阅读和学习这些代码,开发者可以更好地理解和运用设计模式,提升代码质量。同时,结合博主提供的博客链接,...
本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与应用,特别是针对刘伟教授的相关课程的课后习题及模拟试题的解答。 设计模式分为三大类:创建型、结构型和行为型模式。...
《Java设计模式》是刘伟老师的一本经典教材,它深入浅出地讲解了软件设计中的重要概念——设计模式。设计模式是经验丰富的开发者在解决常见问题时总结出的通用解决方案,是软件开发中的智慧结晶。这本书的课后习题和...
首先,我们来看"Java设计模式——观察者模式的两种情况": 1. **主动通知**: 在这种情况下,被观察者对象在自身状态发生变化时,会主动调用`Observable`接口提供的`notifyObservers()`方法,将变化通知给所有注册的...
根据提供的标题、描述以及部分内容,本文将深入探讨Java设计模式,并着重分析23种常见的设计模式,以帮助Java程序员更好地理解和应用这些模式。 ### Java设计模式概述 Java设计模式是面向对象软件设计的一种通用可...
在《Java 23种设计模式24状态模式.pdf》中,作者通过详细的讲解和实例,深入探讨了状态模式的概念、动机、结构、分析及应用。 ### 模式动机 状态模式的核心动机在于解决对象状态变化导致的行为变化问题。当一个...
### Java设计模式经典教程知识点概览 #### 一、设计模式概述 设计模式是一种软件设计方法,它为软件开发者提供了一种标准化的方式去解决常见的软件设计问题。设计模式的使用可以提高代码的可读性和可维护性,同时...
《Java与模式——源码》这个主题涉及到的是Java编程语言中的设计模式应用,以及如何通过源代码来理解和学习这些模式。设计模式是软件工程中的一种最佳实践,它们是解决常见问题的经验总结,使得代码更易读、易维护、...
建造者模式是一种结构型设计模式,它允许我们分步骤创建复杂对象,而无需暴露构建过程的内部细节。这种模式在Java编程中非常常见,尤其是在处理需要多种构建方式或需要隔离对象构造过程的场景。 建造者模式的核心...
目录: 前 言 第一部分 大旗不挥,谁敢冲锋——热身篇 第1章 单一职责原则 1.1 我是“牛”类,我可以担任多职吗 1.2 绝杀技,打破你的传统思维 1.3 我单纯,所以我快乐 1.4 最佳实践 ...附录:23个设计模式
在《设计模式实现——观察者模式》这篇博客中,作者可能详细解释了观察者模式的概念、结构以及其在实际编程中的应用。以下是对观察者模式的详细阐述: 1. **模式定义**:观察者模式是一种对象行为型模式,它允许...
《Java与模式》是闫宏大师的一部经典之作,它将古老的哲学智慧——道德经的智慧,巧妙地融入到现代编程语言Java的设计模式之中。这本书不仅深入浅出地讲解了23种经典的设计模式,还提供了丰富的实践案例,旨在帮助...
### 设计模式精解——GoF23中设计模式解析 #### 重要性与起源 设计模式是软件工程领域的一项重要研究,它提供了一系列解决常见软件设计问题的模板。GoF23指的是由Erich Gamma、Richard Helm、Ralph Johnson和John ...
通过程序范例和UML图示来一一解说,书中代码的重要部分加了标注以使读者更加容易理解,再加上图文并茂,对于初学者还是程序设计高手来说,这都是一本学习和认识JAVA设计模式的一本好书。(注意,本资源附带书中源...
在编程世界中,Java设计模式是面向对象编程领域的一个重要概念,它为解决常见的软件设计问题提供了可重用的解决方案。对于新手来说,设计模式可能显得深奥难懂,但它们实际上是经验丰富的开发者用来提高代码质量、可...
### JAVA设计模式总结之23种设计模式及六大原则 #### 一、设计模式之六大原则 ##### 总原则:开闭原则(Open Close Principle) 开闭原则是设计模式中最核心的原则之一,它强调的是软件实体(类、模块、函数等)...