策略模式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()
相關文章
相關標籤/搜索