第22章 行为型模式—状态模式

1. 状态模式(State Pattern)的定义

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

  ①状态和行为,它们的关系可以描述为“状态决定行为

  ②因状态是在运行期被改变,行为也会在运行期根据状态的改变而改变。看起来,同一个对象,在不同的运行时刻,行为是不一样的,就像是类被修改了一样

(2)状态模式的结构和说明

  ①Context:环境,也称上下文,通常用来定义客户感兴趣的接口,同时维护一个来具体处理当前状态的实例对象

  ②State:状态接口,用来封装与上下文的一个特定状态所对应的行为。

  ③ConcreteState:具体实现状态处理的类,每个类实现一个跟上下文相关的状态的具体处理。

2. 思考状态模式

(1)状态模式的本质:根据状态来分离和选择行为

(2)状态和行为

  ①状态模式的功能就是把状态和状态对应的行为分离出来,每个状态所对应的功能处理封装在一个独立的类里。通过维护状态的变化,来调用不同状态对应的不同功能。

  ②为了操作不同的状态类,定义一个状态接口来约束它们,这样外部就可以面向这个统一的状态接口编程,而无须关心具体的状态类实现了。

  ③状态和行为是相关联的,它们的关系可以描述为状态决定行为。因状态是在运行期被改变,行为也会在运行期根据状态的改变而改变,看起来,同一个对象,在不同的运行时刻,行为是不一样的,就像是类被修改了一样。

(3)行为的平行性

  ①注意是平行性,而不是平等性。所谓的平行性指的是各个状态的行为所处的层次是一样的,相互独立的、没有关联的,是根据不同的状态来决定到底走平行线的哪一条。因为行为是不同的,当然对应的实现也是不同的,相互之间是不可替换的

  ②平等性:强调用的可替换性,大家是同一行为的不同描述或实现,因此在同一个行为发生的时候,可以根据条件挑选任意一个实现来进行相应的处理。

  ③状态模式的结构和策略模式的结构完全一样。但是它们的目的、实现、本质却完全不同。还有行为之间的特性也是状态模式和策略模式的一个很重要的区别,状态模式的行为是平行性,不可相互替换的;而策略模式的行为是平等的,是可以相互替换的

(4)Context和state

  ①在状态模式中,上下文持有state对象,但上下文本身并不处理跟状态相关的行为,而是把处理状态的功能委托给了状态对应的状态处理类来处理

  ②在具体的状态处理类经常需要获取上下文自身的数据,甚至在必要的时候回调上下文中的方法。因此,通常将上下文自身当作一个参数传递给具体的状态处理类

  ③客户端一般只和上下文交互。客户端通常不负责运行期间状态的维护,也不负责决定后续到底使用哪一个具体的状态处理对象,这点与策略模式是不同的

(5)不完美的OCP体验(开闭原则)

  ①修改功能:由于每个状态对应的处理己经封装到对应的状态类中了,要修改己有的某个状态的功能,直接进行修改那个类就可以了,对其他程序没有影响。

  ②添加新的实现类:得修改Context中request方法这不完全遵循OCP原则。这要说明一下,设计原则是大家在设计和开发中尽量去遵守的,但不是一定要遵守,尤其是完全遵守。因为实际开发中,完全遵守那些原则几乎是不可能完成的任务。

(6)创建和销毁状态对象

  ①如果要进入的状态在运行时是不可知的,而且上下文是比较稳定的,不会经常改变状态,而且使用也不频繁的,可以在需要状态对象的时候创建,使用完销毁它们

  ②如果状态改变很频繁,也就是需要频繁的创建状态对象,而且状态对象还存储着大量的数量信息,这种情况可以提前创建它们并且始终不销毁

  ③如果无法确定状态改变是否频繁,而且有些状态对象的数据量大,有些比较小,一切都是未知的,可以采用延迟加载和缓存结合的方式,就是当第一次需要使用状态对象时创建,使用完后并不销毁对象,而是把这个对象缓存起来,等待一下次使用,而且在合适的时候,由缓存框架销毁状态对象。在实际工程开发过程中,这个方案是首选,因为它兼顾了前两种方案的优点,又避免了它们的缺点。

3. 状态的维护和转换控制

(1)在上下文中维护

因状态本身通常被实现为上下文对象的状态,因此可以在上下文中进行状态进行集中的转换,但这里一般会出现较多的if…else语句。这种方法适合那种状态转换的规则是一定的,一般不需要进行什么扩展规则的情况。(如投票管理的例子)

(2)在状态的处理类中维护

  当每个状态处理对象处理完自身状态所对应的功能后,可以根据需要指定后继状态,以便让应用能正确处理后续的请求。这种方法适合应用在那种状态的转换取决于前一个状态动态处理的结果,或者依赖于外部数据的情况。(如电梯状态管理的例子)

4. 状态模式的优缺点

(1)优点

  ①简化应用逻辑控制。因使用单独的类来封装一个状态的处理,使得代码结构化和意图更清晰,从而简化应用的逻辑控制。对于依赖状态的if-else,理论上来说,都可以使用状态模式来实现,把每个if或else块定义一个状态来代表。

  ②更好地分离状态和行为。状态模式通过设置所有状态类的公共接口,使得应用程序只需关心状态的切换,而不用关心这个状态对应的真正处理。

  ③更好的扩展性。引入状态处理的公共接口后,使得扩展新的状态变得非常容易,只需增加一个实现类即可。

(2)缺点:子类膨胀问题,一个状态对应一个状态处理类,会使得程序引入太多的状态类。

5. 状态模式的使用场景

(1)条件、分支判断语句的替代者。如果一个操作中含有庞大的if-else分支语句时,而且这些分支依赖于该对象的状态可以考虑使用状态模式。

(2)行为随状态改变而改变的场景。这也是状态模式的根本出发点,例如权限设计,人员的状态不同即使执行相同的行为结果也会不同,在这种情况下可以考虑使用状态模式。

6. 相关模式

(1)状态模式和策略模式

  留在策略模式一章去讲。可见后面的章节。

(2)状态模式和观察者模式

  ①这两个模式都是在状态发生改变时触发行为,只不过观察者模式的行为是固定的,那就是通知所有的观察者状态模式是根据状态来选择不同的处理

  ②观察者模式是当被观察者对象的状态发生改变的时候,触发观察者联动,具体如何处理观察者模式是不管的。而状态模式的主要目的是在于根据状态和选择行为。

  ③这两个模式可以结合使用,比如在观察者模式的观察者部分,当被观察对象的状态发生了改变,触发通知了所有观察者后,观察者可以使用状态模式,也根据通知过来的状态选择相应的处理。

(3)状态模式和单例模式(或享元模式)

  ①这两者可结合使用,把状态模式中的状态处理类实现成单例,

  ②也可以结合享元模式使用,由于状态模式把状态对应的行为分散到多个状态对象中,会造成很多细粒度的状态,可以把这些状态处理对象通过享元模式来共享,从而节省资源。

时间: 2024-10-21 03:12:52

第22章 行为型模式—状态模式的相关文章

行为型模型 状态模式

行为型模型 状态模式 Context:用户对象        拥有一个State类型的成员,以标识对象的当前状态: State:接口或基类         封装与Context的特定状态相关的行为: ConcreteState:接口实现类或子类         实现了一个与Context某个状态相关的行为. 适用于:         对象的行为,依赖于它所处的当前状态.行为随状态改变而改变的场景. /** * 行为型模型 状态模式 * State模式也叫状态模式,是行为设计模式的一种. * St

Java设计模式(十) 备忘录模式 状态模式

(十九)备忘录模式 备忘录模式目的是保存一个对象的某个状态,在适当的时候恢复这个对象. class Memento{ private String value; public Memento(String value){ this.value = value; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } } class Storage

java设计模式--行为型模式--状态模式

什么是行为型模式,小编觉得就是对行为的一种描述啦,一种对某种行为模型的定义. 状态模式: 1 状态模式 2 概述 3 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 4 5 6 适用性 7 1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为. 8 9 2.一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态. 10 这个状态通常用一个或多个枚举常量表示. 11 通常,有多个操作包含这一相同的条件结构.

21 行为型模式-----状态模式

模式动机(State Pattern):软件系统中,每一个模块在不同的环境下可能发挥着不同的作用,表现为同一对象可能有多种不同的状态,而每种状态下可能有不同的行为.在UML图中,可以用状态图来表示.在程序设计中,我们引入一个抽象状态接口,其中封装了与当前环境状态相关的行为,然后定义具体的状态实现类,根据状态的不同实现不同的行为,并且负责状态之间的切换操作. 参与者: TCPConnection:(当前工作环境 Context):维护一个状态接口的实例,这个实例表示当前环境所处的状态. TCPSt

设计模式(行为型)之状态模式(State Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(行为型)之模板方法模式(Template Method Pattern)>http://blog.csdn.net/yanbober/article/details/45501715 概述 状态模式用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题.当系统中

[19/05/02-星期四] GOF23_行为型模式(状态模式、观察者模式、备忘录模式)

一.状态模式 [状态接口] /*** * 房间"状态"接口 */ package cn.sxt.state; public interface State { void handle(); } [管理状态类] /*** * 环境.上下文类, 管理房间的状态 *如果这是银行系统,这个类就是账号,根据状态的不同,进行不同的操作 */ package cn.sxt.state; public class HomeContext { private State state; public vo

行为模式-状态模式

行为型模式又可以分成以下四类:第一类:通过父类与子类的关系进行实现.第二类:两个类之间.第三类:类的状态.第四类:通过中间类 状态模式属于第三类,类的状态 当状态改变时,行为也会发生相应变化 下面以投票为例 package behavior.pattern.status.status.example; public interface VoteState { /** * 处理状态对应的行为 * @param user 投票人 * @param voteItem 投票项 * @param vote

8.js模式-状态模式

1. 状态模式 var offLightState = function(light){ this.light = light; } offLightState.prototype.buttonWasPressed = function(){ console.log('弱光'); this.light.setState(this.weakLightState); } var weakLightState = function(light){ this.light = light; } weakL

设计模式—策略模式 状态模式

一 策略模式 应用场景 1. 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为. 2. 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现. 3. 对客户隐藏具体策略(算法)的实现细节,彼此完全独立. 优点 1. 策略模式提供了管理相关的算法族的办法.策略类的等级结构定义了一个算法或行为族.恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码. 2. 策略模式提供了可以替换继承关系的办法.继承可以处理多种算法或行为.如