策略模式Strategy 定义:定义一系列的算法,把它们一个个封装起来,而且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活、可维护、可扩展。 策略算法对算法调度具备平等性,算法仅仅是一种性质相同而行为不一样的处理,地位相同,可相互替换,算法之间没有依赖关系。 算法
—抽象策略角色: 策略类,一般由一个接口或者抽象类实现。
—具体策略角色:包装了相关的算法和行为。
—环境角色:持有一个策略类的引用,最终给客户端调用。 服务器
策略模式UML图示
应用场景:
一、 多个类只区别在表现行为不一样(性质同样,但行为不一样),可使用Strategy模式,在运行时动态选择具体要执行的行为。
二、 须要在不一样状况下使用不一样的策略(算法),或者策略还可能在将来用其它方式来实现(动态)。
三、 对客户隐藏具体策略(算法)的实现细节(只公开一个功能,隐藏此功能实现的细节),彼此彻底独立。
this
策略模式之惑 spa
谁来选用策略模式?有2种状况:调用者,调用者选择具体的策略算法 ,而后把这个策略算法设置给上下文(发工资示例);服务者,由上下文(服务器端)选择具体的策略算法(容错恢复示例)。 .net
策略模式扩展问题 翻译
针对调用策略模式的2种角色差别,对策略模式的扩展也不尽相同。 设计
(1)对由调用者(客户端)调用的策略模式,具体的作法是:先写一个策略算法类来实现新的要求,而后在客户端使用的时候指定使用新的策略算法类就能够了。《参见:桥接模式(单纬度的)》 code
(2)对服务端调用的策略模式,以容错恢复为例,能够将Context使用工厂方法(Context里作的是策略选择,能够经过改造实现动态配置)。 对象
=================================================================== 继承
装饰模式Decorator
定义:在没必要改变原类文件和使用继承的状况下,动态的扩展一个对象的功能。它是经过建立一个包装对象,也就是装饰来包裹真实的对象。实用了用一个对象去包含另外一个对象的目的,这样就容许用户动态的向一个对象中添加额外的功能,并且最重要的是,这2种对象是彻底独立的,并且是同质的(继承……)。
特色:(1) 装饰对象和真实对象有相同的接口。这样客户端对象就能够和真实对象相同的方式和装饰对象交互。(2) 装饰对象包含一个真实对象的引用(reference)(3) 装饰对象接受全部来自客户端的请求。它把这些请求转发给真实的对象。(4) 装饰对象能够在转发这些请求之前或之后增长一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就能够在外部增长附加的功能。在面向对象的设计中,一般是经过继承来实现对给定类的功能扩展。
装饰模式:Decorator常被翻译成“装饰”,我以为翻译成“油漆工”更形象,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象咱们称为Decoratee,这两个实体在Decorator模式中是必须的。
Decorator模式定义:
动态给一个对象添加一些额外的职责,就像在墙上刷油漆。使用Decorator模式相比用生成子类方式达到功能的扩展显得更加灵活。
为何使用Decorator?
咱们一般可使用继承来实现功能的扩展,若是这些须要扩展的功能种类繁很繁多,那么必生成不少子类,增长系统的复杂性,同时,使用继承实现功能扩展,咱们必须可预见这些扩展功能,这些功能是编译时就肯定了,是静态的。
使用Decorator的理由是:这些功能须要由用户动态决定加入的方式和时机,Decorator提供了“即插即用”的方法,在运行期间决定什么时候增长何种功能。
如何使用?
咱们先创建一个接口:
public interface Work { public void insert(); }
接口Work又一个具体实现:插入方形桩或圆形桩,这两个区别对Decorator是无所谓。咱们以插入方形桩为例:
public class SquarePeg implements Works { public void insert() { System.out.println("方形桩插入"); } }
如今有一个应用,须要在桩打入前,挖坑,在打入后,在桩上钉木板,这些额外功能是动态,能够随意增长调整修改。
那么咱们使用Decorator模式,这里方形桩SquarePeg是decoratee,咱们须要在decoratee上刷些漆,这些油漆就是那些额外的功能。
public class Decorator implements Work { private Work work; public Decorator(Work work) { this.work = work; } public insert() { beforeInsert(); work.insert(); afterInsert(); } public beforeInsert() { } public afterInsert() { } }
装饰模式就这样出来,咱们如何调用:
Work squarePeg = new SequarePeg(); Work decorator = new Decorator(squarePeg); decorator.insert()