一、引子
状态模式自身结构非常简单——前面刚刚介绍了几个结构比较简单的设计模式,和他们一样,状态模式在具体实现上留下了可变换的余地。我前面已经介绍过它的孪生兄妹策略模式了,大家可以两者比较着阅读。本文将会讨论两者的区别。
二、定义与结构
GOF《设计模式》中给状态模式下的定义为:允许一个对象在其内部状态改变时改变它的行为。这个对象看起来似乎修改了它的类。看起来,状态模式好像是神通广大——居然能够“修改自身的类”!
能够让程序根据不同的外部情况来做出不同的响应,最直接的方法就是在程序中将这些可能发生的外部情况全部考虑到,使用if else
语句来进行代码响应选择。但是这种方法对于复杂一点的状态判断,就会显得杂乱无章,容易产生错误;而且增加一个新的状态将会带来大量的修改。这个时候“能
够修改自身”的状态模式的引入也许是个不错的主意。
状态模式可以有效的替换充满在程序中的if else语句:将不同条件下的行为封装在一个类里面,再给这些类一个统一的父类来约束他们。来看一下状态模式的角色组成吧:
1) 使用环境(Context)角色:客户程序是通过它来满足自己的需求。它定义了客户程序需要的接口;并且维护一个具体状态角色的实例,这个实例来决定当前的状态。
2) 状态(State)角色:定义一个接口以封装与使用环境角色的一个特定状态相关的行为。
3) 具体状态(Concrete State)角色:实现状态角色定义的接口。
类图如下,结构非常简单也与策略模式非常相似。
三、实现
由于状态模式结构非常简单,所以在这里罗列一些反映状态模式实现结构的代码没有什么太大的作用。如果你有兴趣的话可以按照上面类图来编写一下。
在引子中已经提到,状态模式在具体实现上存在不同的方案。因此这里重点就这些不同的实现方式进行介绍和讨论。
首先,实现时是否将状态角色、具体状态角色暴露给客户程序?按照GOF的建议是不希望将状态角色暴露给客户程序的,与客户程序打交道的仅仅是使用环境角
色,客户是不知道系统是怎么实现的,更不关心什么有几个具体状态。但是当使用环境角色中的初始状态紧紧依赖于客户程序时,适乎暴露是在所难免的——这就与
策略模式异常相似了!
具体状态角色中的行为一般是与使用环境角色密切相关的。因此这里便有了一个小细节:我们把使用环境角色作为参数
传递进入具体状态角色后,是在具体状态角色中来实现状态响应行为;还是仅仅调用在使用环境角色中已经实现了的方法?由于这些行为往往与使用环境角色相关,
所以按照《重构》一书的“指导”——后一种实现方法是比较地道的。
从定义可知,状态模式是要应对状态转换的。那么状态的转换在哪里定
义呢?你可以选择在使用环境角色的代码中来表现出来,当然这便意味着状态转变的规则就固定下来了。GOF还给出了另外一种稍微灵活一点的实现方式:在每一
个具体状态角色中来指定后续状态以及何时进行转换。
其实在java强大的反射机制的支持下,我们还可以将状态的转换做的更加灵活——
我们可以将状态转换的规则写在.xml等等的配置文件里面甚至是数据库中,我们姑且叫做状态转换表。进行转换前,根据状态转换表来读取下一个状态,然后利
用反射获得具体的状态对象……。看起来很不错的样子,只是效率可能低一些,在企业应用中这应该不是最重要的。
状态模式已经被我们想
象着“实现”了一番。那么状态模式的引入会给我们的程序带来哪些优势呢?前面我们已经说过:状态模式的引入免除了代码中复杂而庸长的逻辑判断语句。而且具
体状态角色将具体状态和它对应的行为封装了起来,这使得增加一种新的状态变得简单一些。而且如果设计合理得话,具体状态角色可以被重用(和策略模式一样,
可以考虑使用享元模式来实现)。
使用状态模式也会带来一些问题。每个状态对应一个具体的状态类,使得整体分散,逻辑不太清晰。当然对于一个状态非常多的系统,状态模式带来的优点还是大于它的缺点的。
由上面的分析就可以很明确的知道什么时候该使用状态模式了。下面是GOF在《设计模式》中给出的状态模式的适用情况:
1) 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
2) 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。
四、状态VS策略
仔细对比状态模式和策略模式,难免会产生疑问:这两个明明是一个东西嘛!下面我们就来分析下两者区别。
首先我要声明,在实际应用中只要能够使得你的代码灵活漂亮起来,何必计较这些方方面面的差别呢?
Brandon
Goldfedder在《模式的乐趣》里是怎么说的:“strategy模式在结构上与state模式非常相似,但是在概念上,他们的目的差异非常大。区
分这两个模式的关键是看行为是由状态驱动还是由一组算法驱动,这条规则似乎有点随意,但是在判断时还是需要考虑它。通常,State模式的“状态”是在对
象内部的,Strategy模式的“策略”可以在对象外部,不过这也不是一条严格、可靠的规则。”
我很同意Brandon Goldfedder的观点。这两个模式的划分,就在于使用的目的是不同的——策略模式用来处理算法变化,而状态模式则是处理状态变化(好玄乎阿)。
策略模式中,算法是否变化完全是由客户程序开决定的,而且往往一次只能选择一种算法,不存在算法中途发生变化的情况。从《深入浅出策略模式
》中的例子可以很好的看出。
而状态模式如定义中所言,在它的生命周期中存在着状态的转变和行为得更改,而且状态变化是一个线形的整体;对于客户程序来言,这种状态变化往往是透明的。
五、总结
比较笼统地介绍了下状态模式,并将它和非常相近的策略模式进行了比较。欢迎大家学习指正。
出处:http://dev.yesky.com/438/2164938.shtml
分享到:
相关推荐
在深入浅出Java设计模式的高清中文PDF文件中,首先以一个生活化的例子引出了工厂模式的概念,介绍了工厂模式在面向对象编程中的重要性和实用性。文档详细讲解了20多种Java设计模式,并且在讲解的过程中包含了丰富的...
总的来说,深入浅出设计模式附书源码Java版源代码是一份宝贵的资源,对于想要提升Java设计能力的开发者来说,它提供了一个实践和学习设计模式的绝佳平台。通过实际操作和调试代码,你可以更好地理解和掌握这些模式,...
本资源"深入浅出设计模式C#Java版"是针对这两种主流编程语言介绍设计模式的经典著作,旨在帮助开发者理解和应用这些模式。 1. **单例模式**:确保一个类只有一个实例,并提供全局访问点。在C#中,可以使用`密封`和`...
总结来说,《深入浅出设计模式》是一本以易懂的方式介绍设计模式的优秀教材,结合书中给出的Java代码,无论你是Java开发者还是其他语言的程序员,都能从中受益,掌握设计模式这一核心的软件工程技能。通过学习本书,...
《深入浅出Java》这本书很可能使用了Head First的教学方法,这是一种以大脑科学为基础的学习模式,通过视觉化、故事化和互动的方式,使学习过程既有趣又有效。书中可能包含大量图表、漫画和游戏,帮助你以轻松的方式...
《深入浅出设计模式》是一本旨在帮助开发者理解和应用设计模式的经典书籍,它提供了C#和JAVA两种语言的源代码实现,使得学习者可以通过实际操作来加深对设计模式的理解。 1. **设计模式的基本概念**: 设计模式...
《深入浅出设计模式》是一本专为Java开发者编写的关于设计模式的中文教材,它旨在帮助读者理解和掌握设计模式这一编程领域的核心概念。设计模式是软件开发中的经验总结,是解决常见问题的有效模板,通过将成熟的设计...
根据提供的信息,我们可以深入探讨《Head First 设计模式》中的状态模式这一章节。状态模式是设计模式中的一种,主要用于处理对象状态变化时的行为差异。接下来,我们将详细解析状态模式的概念、应用场景、结构组成...
《Java设计模式》是刘伟老师的一本经典教材,它深入浅出地讲解了软件设计中的重要概念——设计模式。设计模式是经验丰富的开发者在解决常见问题时总结出的通用解决方案,是软件开发中的智慧结晶。这本书的课后习题和...
本资料"深入浅出Java 23种设计模式"旨在帮助开发者理解和应用这23种经典设计模式。 首先,我们要了解设计模式的三大类别:创建型模式、结构型模式和行为型模式。创建型模式关注对象的创建过程,如单例模式...
《Java设计模式之禅》是一本深入浅出讲解设计模式的书籍,书中不仅包含23种经典设计模式的案例,还详细介绍了设计模式背后的思想和原则,适合初学者以及对设计模式有一定了解的程序员阅读。本书旨在帮助读者理解如何...
5.8StatePattern(状态模式) 248 5.8.1定义 248 5.8.2现实例子——心情好坏 250 5.8.3C#实例——账户分类 250 5.8.4Java实例——汽车的变速档 258 5.8.5优势和缺陷 261 5.8.6应用情景 261 5.9...
《深入浅出设计模式》是一本旨在帮助读者理解和掌握设计模式的书籍,适合那些希望深入研究设计模式的IT从业者。这本书可能与《HEAD FIRST设计模式》相辅相成,通过不同的讲解方式来帮助读者更全面地理解这一领域。 ...
《深入浅出设计模式(Java版)》这本书是面向Java开发者的一本全面解析设计模式的指南。它深入探讨了各种设计模式,旨在帮助读者更好地理解和应用这些模式来提高代码的可读性、可维护性和可扩展性。以下是该书可能...
《深入浅出设计模式样章》是一本专为软件开发者准备的指南,旨在帮助读者理解和掌握设计模式这一核心编程概念。设计模式是软件工程中经过时间验证、在特定情境下解决常见问题的有效方法,它提供了可重用的解决方案,...
本电子书集合深入浅出地剖析了Java设计模式,旨在帮助开发者理解和应用这些模式,提升编程技能。 首先,让我们探讨“设计模式”的概念。设计模式并不是具体的代码或库,而是一种描述在特定编程环境中常见问题的最佳...