策略模式Strategy 定义:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活、可维护、可扩展。 策略算法对算法调度具有平等性,算法仅仅是一种性质相同而行为不同的处理,地位相同,可相互替换,算法之间没有依赖关系。
—抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
—具体策略角色:包装了相关的算法和行为。
—环境角色:持有一个策略类的引用,最终给客户端调用。
策略模式UML图示
应用场景:
1、 多个类只区别在表现行为不同(性质一样,但行为不同),可以使用Strategy模式,在运行时动态选择具体要执行的行为。
2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现(动态)。
3、 对客户隐藏具体策略(算法)的实现细节(只公开一个功能,隐藏此功能实现的细节),彼此完全独立。
策略模式之惑
谁来选用策略模式?有2种情况:调用者,调用者选择具体的策略算法 ,然后把这个策略算法设置给上下文(发工资示例);服务者,由上下文(服务器端)选择具体的策略算法(容错恢复示例)。
策略模式扩展问题
针对调用策略模式的2种角色差异,对策略模式的扩展也不尽相同。
(1)对由调用者(客户端)调用的策略模式,具体的做法是:先写一个策略算法类来实现新的要求,然后在客户端使用的时候指定使用新的策略算法类就可以了。《参见:桥接模式(单纬度的)》
(2)对服务端调用的策略模式,以容错恢复为例,可以将Context使用工厂方法(Context里做的是策略选择,可以通过改造实现动态配置)。
===================================================================
装饰模式Decorator
定义:在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。实用了用一个对象去包含另一个对象的目的,这样就允许用户动态的向一个对象中添加额外的功能,而且最重要的是,这2种对象是完全独立的,而且是同质的(继承……)。
特点:(1) 装饰对象和真实对象有相同的接口。这样客户端对象就可以和真实对象相同的方式和装饰对象交互。(2) 装饰对象包含一个真实对象的引用(reference)(3) 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。(4) 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。
示例:Decorator模式