1. 程式人生 > 實用技巧 >《大話設計模式》讀書筆記(一)

《大話設計模式》讀書筆記(一)

寫在前面

這學期開了一門叫做設計模式的課,正好自己一直想看《大話設計模式》,藉著這個機會跟著課堂把這本書看完了。受益還是蠻大的,很多模式其實自己在平常編碼中都有用到。

類圖中的關係

在正式開始學習前,需要先複習一下類圖的相關知識。因為在設計模式中大量使用類圖來表達一個設計模式的結構。

類圖複習


首先我們看到了一個矩形框,他代表一個類。類圖分為三層,第一層表示類的名稱,如果是抽象類則用斜體表示。第二層是類的特性,通常包括欄位和屬性。第三層是類的操作,通常是方法或行為。”+“表示“public”,“-”表示“private,”#“表示”protected“。

介面


如圖所示,為介面的一種表示方式,與類圖的區別主要是頂部有<<interface>>

的顯示。非常明顯的,第一行是介面名稱,第二行是介面方法。介面還可以用棒棒糖表示法來表示:

如圖所示,唐老鴨類實現了“講人話介面"。

類與類的關係——繼承

首先自然是繼承關係了,如圖:

繼承關係使用空心三角+實線來表示,其中箭頭指向父類。

類與介面的關係——實現

如圖所示,實現關係通過空心三角+虛線來表示,箭頭指向被實現的介面。

類與類的關係——關聯

關聯關係,如圖所示,通過實線箭頭表示。關聯關係表示兩者之間具有使用關係,如圖中的企鵝需要知道(引用)了這個類。

類與類的關係——聚合

聚合關係代表一種弱的“擁有關係“,即A物件可以包含B物件,但B物件不是A的一部分。圖中的例子舉的不太好,但用面向物件的方式理解的話是沒有問題的,即雁群類中包含一個大雁List,但大雁類中並不包含雁群類。

類與類的關係——組合(合成)

組合關係代表一種強的“擁有關係”,體現了嚴格的部分和整體的關係,部分和整體的生命週期一致。組合關係用實心的菱形 + 實線箭頭來表示。另外,我們在連線上標了兩個數字,這被稱為基數。表示這一端的類可以有幾個例項。一隻鳥有兩隻翅膀,所以這裡就標著1和2了。另外,關聯關係和聚合關係都可以標註基數。

類與類的關係——依賴

依賴關係,表示該類在另一個類的方法引數上,表明該類的執行需要此類,如動物的新陳代謝需要氧氣和水,則動物依賴氧氣和水。依賴關係用虛線箭頭來表示。

0.簡單工廠模式(Simple Factory Pattern)

解決的問題

在開發時,很多時候都會遇到多個類有共同父類的情況。一旦類多起來就記不住名稱了。如果我們希望在使用這些子類時不需要知道具體的類名,只要知道一個引數就可以給我們返回一個需要的物件,那麼就用得到簡單工廠模式了。

類圖結構

簡單工廠模式如圖所示結構,這個類圖中包含三類角色:

  1. Factory(工廠角色)

    工廠角色即工廠類,它是該模式的核心角色。工廠類中提供了核心方法factoryMethod(),返回一個抽象產品類,即所有的具體產品類的父類。

  2. Prodcut(抽象產品角色)

    抽象產品角色是簡單工廠模式中所有物件的父類,負責描述所有例項共有的公共介面。

  3. ConcreteProduct(具體產品角色)

    具體產品角色是簡單工廠模式的建立目標。

其中,核心類Factory大概長這樣:

public class Factory{
    public static Product factoryMethod(String arg){
        if(arg.equals("A")){
            return new ConcreteProductA();
        }
        if(arg.equals("B")){
            return new ConcreteProductB();
        }
    }
}

好處與壞處

大致來講,簡單工廠模式通過一個工廠類封裝了具體的獲得實現類的邏輯,使得使用者不需要知道具體的實現類即可很快的獲得一個需要的實體類。

但由於工廠類包含了所有的邏輯,一旦其崩潰,則整個系統都會崩潰。同時隨著類的增多需要不斷修改工廠類,工廠類的業務邏輯會十分複雜,違背了開閉原則。

Tips

可以看到,這裡對簡單工廠模式標註的是0,代表他並不屬於23種設計模式。但為什麼還需要了解他呢,因為他使用的實在是太頻繁了,而且瞭解簡單工廠模式可以更好的理解23種設計模式中的工廠方法模式。

1.策略模式(Strategy Pattern)

解決的問題

策略模式是一種定義一系列演算法的方法,從概念上看,所有這些演算法完成的都是相同的工作,只是實現不同。因此,我們可以使用策略模式解決相同概念但不同實現的工作,如商場打折。

類圖結構

假設我們現在有一個超市正在舉行打折活動,打折活動分為兩種——1.打折收費 2.返利收費。我們通過策略模式實現這個需求。

類圖如下:

在這個類圖中,CashContext類通過構造方法傳入具體的收費策略,然後根據不同的收費策略來獲得計算結果:

public class CashContext{
    private CashSuper cs;
    public CashContext(CashSuper cs){
        this.cs = cs;
    }
    public double getResult(double money){
        return cs.acceptCash(money);
    }
}

而CashNormal、CashRebate、CashReturn這三個類都繼承自CashSuper類,實現了acceptCash()方法:

public class CashNormal extends CashSuper{
    @override
    public double acceptCash(double money){
        return money;
    }
}

這樣,我們在使用的時候只需要new一個CashContext物件,然後傳入對應的子類即可。

好處與壞處

策略模式的好處十分顯而易見,外部不需要知道內部的具體實現,只需要呼叫同樣的方法就可以做出不同的實現。可以很好地提取出公共功能。

壞處也很明顯,策略模式並沒有減輕客戶端需要判斷的壓力。我們可以使用策略模式+簡單工廠模式的方式來減輕客戶端的職責。

總結

這次的部落格是開篇之章,主要是複習了類圖的基本概念,並記錄了簡單工廠模式和策略模式。