設計模式——策略模式

爲何使用策略模式?java

分析一個鴨子父類和各類鴨子子類之間的fly()方法如何寫。算法

有幾點須要注意,先是不通鴨子飛的方式可能不同,甚至有的鴨子不會飛。編程

①若是直接在父類中加入fly()的實現,那麼全部的子類鴨子都只會同一種飛法,這確定是不對的。函數

②若是在子類中重寫父類的fly()方法,那麼之後每加入一個新品種鴨子,都須要重寫fly()函數spa

③直接繼承fly()方法可能不是最佳答案,若是利用接口呢?咱們將fly()從父類中取出,放進一個Flyable接口中,只有會飛的鴨子須要實現這個接口。看似可行,可是這使得代碼不可複用,每一個子類都必須實現fly()方法。設計

 

使用緣由:code

相似的,在實現某一個功能時有多重算法或者策略,咱們根據不一樣環境和條件選擇不一樣的算法和策略來完成此功能。對象

在這基礎上,咱們還須要一種對已有代碼影響最小的方式來修改代碼,而且能夠花費較少時間來重寫代碼繼承

什麼是策略模式?接口

策略模式:定義了算法族,分別封裝起來,讓他們(每種算法)之間能夠互相替換,此模式讓算法的變化獨立於使用算法的客戶。

設計原則①:找出應用中可能須要變化之處,把它們獨立出來,不要和那些不須要變化的代碼混在一塊兒。

設計原則②:針對接口編程,而不是針對實現編程。

根據設計原則①,分析咱們的類,咱們很容易發現,fly()方法是如今變化的部分,因此咱們應當將fly()單獨拿出。

根據設計原則②,咱們應當將fly設置爲一個接口,而後下面有不一樣的實現此接口的類。

 

而後開始整合:

①須要在原duck類中「加入一個實例變量」,「flyBehavior」,聲明爲接口類型(而不是具體類實現類型),每一個鴨子對象都會動態的設置這些變量以在運行時引用正確的行爲類型。

②在實現duck的fly函數的時候只須要調用「flyBehavior」接口的fly方法便可。

③如何制定「flyBehavior」接口的具體實現?只需在duck的子類的構造函數中,爲「flyBehavior」接口指向一個具體實現便可。

public class MallardDuck extends Duck{
    public MallardDuck(){
        flyBehavior=new FlyWithWings();//將「flyBehavior」接口指向它的具體實現類
    }
}

到此,基本完成,可是除此以外,咱們還以在運行時經過一個setflyBehavior的方法,來從新制定一個鴨子的飛行方式,即應用了多態。

 

再分析此處應用的策略模式:

算法族:指的是fly接口的不一樣實現類,由於多態,因此fly接口能夠指向它的不一樣的實現類。

算法的變化獨立於客戶:由於客戶只是調用了fly接口的一個實現類,具體實現類的代碼改動並不會影響使調用它的客戶的代碼進行改動。

選擇策略:duck子類的構造函數中爲flyBehavior指向一個fly實現類,就是爲fly選擇了一種算法,也即一種fly策略。

相關文章
相關標籤/搜索