状态(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设计模式,目录:前言,UML建模技术,深入浅出UML类图,从招式与内功谈起——设计模式概述,面向对象设计原则,工厂三兄弟之简单工厂模式,工厂三兄弟之工厂方法模式,工厂三兄弟之抽象工厂模式,确保对象的唯一...
目录: 前 言 第一部分 大旗不挥,谁敢冲锋——热身篇 第1章 单一职责原则 1.1 我是“牛”类,我可以担任多职吗 1.2 绝杀技,打破你的传统思维 1.3 我单纯,所以我快乐 1.4 最佳实践 ...附录:23个设计模式
通过程序范例和UML图示来一一解说,书中代码的重要部分加了标注以使读者更加容易理解,再加上图文并茂,对于初学者还是程序设计高手来说,这都是一本学习和认识JAVA设计模式的一本好书。(注意,本资源附带书中源...
第3章GoF-CreationalDesignPatterns创建型设计模式 23 3.1SimpleFactoryPattern(简单工厂模式) 24 3.1.1定义 24 3.1.2现实例子——国旗生产厂 26 3.1.3C#实例1——电子付款系统 26 3.1.4C#实例2——学校登录...
第3章GoF-CreationalDesignPatterns创建型设计模式 23 3.1SimpleFactoryPattern(简单工厂模式) 24 3.1.1定义 24 3.1.2现实例子——国旗生产厂 26 3.1.3C#实例1——电子付款系统 26 3.1.4C#实例2——学校登录...
设计模式趣味学习(复习) 设计模式趣味学习(复习) 设计模式与足球(一) 设计模式与足球(二) 设计模式与足球(三) 设计模式与足球(四) 设计模式综合应用实例 设计模式综合应用实例 多人联机射击游戏 多人...
行为图——状态图 uml/activity.mdl //06.行为图——活动图 uml/sequence.mdl //07.交互图——序列图 uml/collaboration.mdl //08.交互图——协作图 (2)UML上机演练源文件(16个实例文件) uml/usecase_product....
行为图——状态图 uml/activity.mdl //06.行为图——活动图 uml/sequence.mdl //07.交互图——序列图 uml/collaboration.mdl //08.交互图——协作图 (2)UML上机演练源文件(16个实例文件) uml/usecase_product....
(3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/abstractfactory //11.2抽象...
(3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/abstractfactory //11.2抽象...
行为图——状态图 uml/activity.mdl //06.行为图——活动图 uml/sequence.mdl //07.交互图——序列图 uml/collaboration.mdl //08.交互图——协作图 (2)UML上机演练源文件(16个实例文件) uml/usecase_product....
面向对象系统分析设计——对象设计,状态模式
状态模式 策略模式 模板方法模式 访问者模式 设计案例 UML 架构 系统架构能力 基本理论 扩展性设计 可用性设计 可靠性设计 一致性设计 负载均衡设计 过载保护设计 协议设计 二进制协议 文本协议 ...
行为图——状态图 uml/activity.mdl //06.行为图——活动图 uml/sequence.mdl //07.交互图——序列图 uml/collaboration.mdl //08.交互图——协作图 (2)UML上机演练源文件(16个实例文件) uml/usecase_product....
行为图——状态图 uml/activity.mdl //06.行为图——活动图 uml/sequence.mdl //07.交互图——序列图 uml/collaboration.mdl //08.交互图——协作图 (2)UML上机演练源文件(16个实例文件) uml/usecase_product....
行为图——状态图 uml/activity.mdl //06.行为图——活动图 uml/sequence.mdl //07.交互图——序列图 uml/collaboration.mdl //08.交互图——协作图 (2)UML上机演练源文件(16个实例文件) uml/usecase_product....
Java 是面向对象的编程语言,对象就是面向对象程序设计的核心。其基本思想是使用对象、类、继承、封装、多态等基本概念来进行程序设计。从现实世界中客观存在的事物(即对象)出发来构造软件系统,并且在系统构造中...
(3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/abstractfactory //11.2抽象...
(3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/abstractfactory //11.2抽象...