为了能在Java应用程序中正确的使用状态模式和策略模式,开发人员需要清楚地知道这两种模式之间的区别。尽管状态模式和策略模式的结构非常相似,它们又同样遵循开闭原则,都代表着SOLID设计原则的'O',但它们的意图是完全不同的。Java中的策略模式是对一组相关的算法进行封装,给调用方提供了运行时的灵活性。调用方可以在运行时选择不同的算法,而不用修改使用策略的那个Context类。使用策略模式的经典例子包括实现加密算法,压缩算法,以及排序算法。另一方面,状态模式使用一个对象可以在不同的状态下表现出不同的行为。真实世界里的对象也是有状态的,并且它们会随着状态的不同而有不同的表现,比方说自动售货机,它只会在hasCoin状态下才能出售物品,如果你不塞硬币进去它是不会售货的。现在你可以很清楚地看到策略模式和状态模式的区别了,它们的目的是不一样的。状态模式可以帮助对象来管理它的状态,而策略模式使得客户端可以选择不同的行为。还有一个不太容易看到的区别是,谁去驱动行为的改变。在策略模式中,是客户端驱动的,它给上下文信息提供了不同的策略,而在状态模式中,状态的迁移是由Context或者State对象自己来管理的。同样的,如果你在State对象里面进行状态的修改,它必须持有Context的引用,也就是说对自动售货机而言,它可以调用setState方法来修改当前Context的状态。另一方面,策略对象不会持有Context的引用 ,它的客户端将选中的策略传递给Context。策略模式和状态模式是最容易碰见的关于Java设计模式的面试题,在这篇关于Java设计模式的文章里,我们将会对这点进行详细的介绍。我们会探索这两种模式的相同点与不同点,这有助于提高你对这两种模式的理解。
状态模式和策略模式的相似点
如果你看下策略模式和状态模式的UML图,它们看起来非常相似。在状态模式中,使用State对象来改变行为的的对象叫Context对象,类似的在策略模式中,使用Strategy对象来改变行为的对象也是Context对象。记住,客户端是和Context对象交互的。在状态模式中,Context代理了状态对象的方法调用,Context中的当前对象就是具体的状态对象,而在策略模式中,Context操作的也是策略对象,这个对象要么作为参数传入进来,要么是在创建Context对象的时候就已经提供了。
这是状态模式的UML图,它画的是Java中的自动售货机的面向对象设计的经典问题。可以看到的是售货机的状态是通过一个接口来表示的,它有具体的实现来代表具体的状态。每个状态也同样持有Context对象的引用,这样它们可以调用Context的方法来迁移到下一个状态中。
这是策略模式的UML图,它实现的是一个排序功能。由于有许多排序算法,因此这个模式使用客户端可以先反使用不同的算法来进行排序。事实上,Java的集合框架中使用的就是这个模式来实现Collections.sort()方法,Java中使用这个方法来进行对象的排序。不同之处在于它并不是允许客户端来选择排序的算法,而是让它们传递一个Comparator或者 Comparable接口的实现来指定比较的策略。
我们再来看一下这两种核心的Java设计模式的一些相似点:
状态模式和策略模式都很容易新增新的状态或者策略,而不会影响到使用它们的Context对象
两种模式都遵循开闭的设计原则,也就是说你的设计对扩展开放而对修改关闭。在这两个模式里,Context对修改是封闭的,新增状态或者策略,你不需要修改其它状态的Context对象,或者只需要很小的改动
正如状态模式中Context对象会有一个初始状态一样,策略模式中的Context通常也有一个默认的策略。
状态模式以不同的状态对象的方式来封装不同的行为,而策略模式以不同的策略对象来封装不同的行为。
这两种模式都依赖具体的子类来实现具体的行为。每一个具体的策略都扩展自一个抽象的策略类,每个状态也都是用来表示状态的接口或者抽象类的子类。
策略模式和状态模式的区别
我们已经了解到这两个模式在结构上非常相似,但它们仍有不同的地方。下面来看下它们之间一些关键的不同点。
策略模式封装了一系列的相关的算法,使用客户端可以在运行时通过组合和委托来使用不同的行为,而状态模式使得对象可以在不同的状态下展现出不同的行为。
这两个模式的另一个不同之处在于状态模式封装的是对象的状态,而策略模式封装的是一个算法或者策略。由于状态是和对象耦合在一起的,它无法重用,而通过策略或者算法独立于它的上下文,使得它们可以重复使用。
状态模式中,状态本身会包含Context的引用,从而实现状态迁移 ,但策略模式则没有Context的引用
具体的策略可以作为一个参数传递给使用它们的对象,比如说Collections.sort()接受一个Comparator,这是一个策略。另状态本身 是 Context对象的一部分,随着时间的迁移,Context对象会从一个状态迁移迁移到另一个状态下。
尽管两种模式都遵循了开闭原则,策略模式还遵循了单一职责原则,因为每个策略都 封装的是独立 的算法,不同的策略独立于其它策略。改变一个策略并不会影响到另一个策略的实现。
从理论上说,策略模式和状态模式还有一个不同,前者定义的是一个对象“如何”去做一件事情,比如说如何对数据进行排序,而另一方面,状态模式定义的是“什么”以及“何时“,比如说一个对象能做什么,某个时间点它处于哪个状态。
状态的迁移顺序在状态模式中是定义好的,而策略模式则没有这样的要求。客户端可以随便选择使用哪个策略。
常见的策略模式的例子都是封装算法,比如说排序算法,加密算法,或者压缩算法。如果你发现代码中需要使用到不同的算法,那么你可以考虑使用策略模式。而如果你需要管理状态进行状态间的迁移,而不希望嵌套许多条件语句,那么状态模式就是你的首选,因为它非常简单.
最后也是最重要的一个区别在于,策略模式是由客户端进行处理的,而状态的改变Context或者State对象都可以进行。
这就是关于Java中策略模式和状态模式的所有区别。正如我所说的,它们在UML图中看起来非常类似,两者都遵循了开闭原则,并且封装了行为。策略模式是用来封装算法或者策略的,它会在运行时作为参数或者组合对象来提供给Context对象,而状态模式则是用来管理状态迁移 的。
原创文章转载请注明出处:
http://it.deepinmind.com
英文原文链接
分享到:
相关推荐
需要注意的是,策略模式和状态模式虽然看起来很相似,但它们的应用场景和实现方式是不同的。策略模式主要用于解决系统与第三方接口进行数据交互的问题,而状态模式主要用于解决状态转换的问题。同时,策略模式需要...
状态模式和策略模式的相似之处在于,它们都涉及到对象行为的动态变化,且都可以通过增加新类来扩展行为,而不修改现有的代码,符合开闭原则。它们都依赖于继承或接口实现来定义具体的行为,例如,策略模式中具体的...
虽然状态模式和策略模式在结构上有一定的相似性,但它们的目的和应用场景有所不同: - **状态模式**:关注的是对象内部状态的变化,状态的改变会导致行为的变化,且状态之间的转换通常是隐式的。 - **策略模式**:...
- 状态模式和策略模式虽然有相似的类图,但它们的意图不同。状态模式是通过改变对象内部的状态来控制对象的行为。 - 上下文将与状态相关的操作委托给当前的具体状态对象处理。 - 上下文可以将自身作为一个参数...
在`Strategy模式实例.docx`文档中,可能会包含具体的策略模式应用示例,如不同的排序算法(冒泡排序、快速排序、插入排序等)的实现,以及如何在上下文中选择和使用这些策略。读者可以通过阅读这个文档,更深入地...
状态模式策略模式很相似,也是将类的“状态”封装了起来,在执行动作时进行自动的转换,从而实现,类在不同状态下的同一动作显示出不同结果。它与策略模式的区别在于,这种转换是“自动”,“无意识”的。
状态模式与策略模式有一定程度的相似性,它们都使用了一个上下文(Context)类,并通过多态基类的派生类实现算法逻辑。区别在于,状态模式中的派生类持有指向上下文对象的引用,并通过这个引用调用上下文中的方法,...
总结来说,享元模式是一种有效的优化手段,特别是在处理大量相似对象时,通过共享内部状态和外部状态的分离,减少了内存开销,提高了系统的运行效率。理解和掌握享元模式对于提升软件设计的灵活性和性能至关重要。
- 策略模式与状态模式类似,但策略模式关注的是算法的不同实现,而状态模式关注的是对象状态变化带来的行为变化。 综上所述,策略模式是一种强大的设计模式,它允许我们在运行时动态选择和切换算法,提高了代码的...
9. **状态模式**:允许对象在其内部状态改变时改变其行为,对象看起来似乎改变了它的类。 10. **访问者模式**:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些...
在技术进步的推动下,电压模式控制也取得了显著的发展,通过新型电路和工艺的改进,现代电压模式控制已经能够提供与电流模式相似甚至更优的性能。例如UCC3570是一款新型电压模式控制器,它结合了先进的电路设计和...
- 策略模式(Strategy):定义一系列算法,并将每一个算法封装起来,使它们可以互相替换。 - 模板方法模式(Template Method):定义一个操作中的算法骨架,而将一些步骤延迟到子类中。 - 访问者模式(Visitor)...
策略模式让算法的变化独立于使用算法的客户。 以上就是PHP设计模式的一些核心概念和应用场景,每个模式都有其独特的优点和适用场景,理解并合理运用这些模式可以极大地提升代码的可读性和可维护性。在实际开发中,...
1. 策略模式(Strategy Pattern):允许在运行时选择算法的行为,如书中提到的“锦囊妙计”例子,通过不同的策略应对不同的情形。 2. 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问,常...
包括策略模式(Strategy)、模板方法模式(Template Method)、观察者模式(Observer)、迭代器模式(Iterator)、访问者模式(Visitor)、职责链模式(Chain of Responsibility)、命令模式(Command)、备忘录模式...
策略模式让游戏逻辑可以根据场景动态选择不同的策略,增加了游戏的多样性和可玩性。 5. **装饰者模式**:在游戏开发中,常常需要动态地为对象添加新的功能,而装饰者模式可以在不改变对象类的前提下,通过包装原...
策略模式让算法独立于使用它的客户而变化,适用于需要在运行时动态选择算法的场景。 4. **Composite(组合)模式**:此模式允许开发者将对象组合成树形结构以表示“部分-整体”的层次结构。Composite 模式使得用户...
包括单例模式、工厂模式、观察者模式、装饰器模式、代理模式、适配器模式、桥接模式、建造者模式、组合模式、享元模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、状态模式、策略模式、模板方法...
- 策略模式:定义一系列算法,并将每一个算法封装起来,使它们可以互相替换,策略对象改变算法的执行。 - 模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。 这些模式的应用能够帮助...
- 状态模式:允许一个对象在其内部状态改变时改变它的行为,看起来像是改变了它的类。 - 策略模式:定义一系列算法,并将每个算法封装起来,使它们可以相互替换。 - 模板方法模式:定义一个操作中的算法骨架,而...