策略模式Strategy、装饰模式Decorator

策略模式Strategy 定义:定义一系列的算法,把它们一个个封装起来,而且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活、可维护、可扩展。 策略算法对算法调度具备平等性,算法仅仅是一种性质相同而行为不一样的处理,地位相同,可相互替换,算法之间没有依赖关系。 算法

—抽象策略角色: 策略类,一般由一个接口或者抽象类实现。
—具体策略角色:包装了相关的算法和行为。
—环境角色:持有一个策略类的引用,最终给客户端调用。
服务器

策略模式UML图示


应用场景:
一、 多个类只区别在表现行为不一样(性质同样,但行为不一样),可使用Strategy模式,在运行时动态选择具体要执行的行为。
二、 须要在不一样状况下使用不一样的策略(算法),或者策略还可能在将来用其它方式来实现(动态)。
三、 对客户隐藏具体策略(算法)的实现细节(只公开一个功能,隐藏此功能实现的细节),彼此彻底独立。
this

优势:
一、  提供了一种替代继承的方法,并且既保持了继承的优势(代码重用)还比继承更灵活(算法独立,能够任意扩展)。
二、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
三、 遵照大部分GRASP原则和经常使用设计原则,高内聚、低偶合。
缺点:
一、 由于  每一个具体策略类都会产生一个新类,因此会增长系统须要维护的类的数量。
解决方案:工厂方法 

策略模式之惑 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()
相关文章
相关标签/搜索