設(shè)計(jì)模式思考 I

前言

最近復(fù)習(xí)設(shè)計(jì)模式,花了不少時(shí)間,由于項(xiàng)目經(jīng)驗(yàn)還比較少,雖然看得懂,能理解,但鑒于個(gè)人比較偏實(shí)踐,不善于記憶,隔一段時(shí)間后,卻很快就忘記了o(╯□╰)o,到真正自己說(shuō)的時(shí)候也說(shuō)不出來(lái)……與其看別人的總結(jié),不如自己再根據(jù)別人的博客再思考整理一番,或許這樣比反復(fù)看的效果會(huì)好些吧。下面是根據(jù)別人的博客和以下幾點(diǎn)思考方式來(lái)重新整理的筆記:
1.這種模式怎么理解?(盡量簡(jiǎn)單易懂)
2.類(lèi)圖怎樣畫(huà)?(代碼怎樣寫(xiě))
3.舉個(gè)栗子?(使用場(chǎng)景)
4.使用這種模式有什么優(yōu)缺點(diǎn)?(遵循什么原則)

相關(guān)代碼示例地址: navyifanr/AndroidTrainingDemo/DesignPattern

設(shè)計(jì)模式六大原則

1.開(kāi)閉原則(Open Close Principle)
開(kāi)閉原則就是說(shuō)對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。在程序需要進(jìn)行拓展的時(shí)候,不能去修改原有的代碼,實(shí)現(xiàn)一個(gè)熱插拔的效果。所以一句話(huà)概括就是:為了使程序的擴(kuò)展性好,易于維護(hù)和升級(jí)。想要達(dá)到這樣的效果,我們需要使用接口和抽象類(lèi),后面的具體設(shè)計(jì)中我們會(huì)提到這點(diǎn)。
參考:https://realm.io/cn/news/donn-felker-solid-part-2/

2.里氏代換原則(Liskov Substitution Principle)
里氏代換原則(Liskov Substitution Principle LSP)面向?qū)ο笤O(shè)計(jì)的基本原則之一。 里氏代換原則中說(shuō),任何基類(lèi)可以出現(xiàn)的地方,子類(lèi)一定可以出現(xiàn)。 LSP是繼承復(fù)用的基石,只有當(dāng)衍生類(lèi)可以替換掉基類(lèi),軟件單位的功能不受到影響時(shí),基類(lèi)才能真正被復(fù)用,而衍生類(lèi)也能夠在基類(lèi)的基礎(chǔ)上增加新的行為。里氏代換原則是對(duì)“開(kāi)-閉”原則的補(bǔ)充。實(shí)現(xiàn)“開(kāi)-閉”原則的關(guān)鍵步驟就是抽象化。而基類(lèi)與子類(lèi)的繼承關(guān)系就是抽象化的具體實(shí)現(xiàn),所以里氏代換原則是對(duì)實(shí)現(xiàn)抽象化的具體步驟的規(guī)范。—— From Baidu 百科
參考:https://realm.io/cn/news/donn-felker-solid-part-3/

3.依賴(lài)倒轉(zhuǎn)原則(Dependence Inversion Principle)
這個(gè)是開(kāi)閉原則的基礎(chǔ),具體內(nèi)容:真對(duì)接口編程,依賴(lài)于抽象而不依賴(lài)于具體。
參考:https://realm.io/cn/news/donn-felker-solid-part-5/

4.接口隔離原則(Interface Segregation Principle)
這個(gè)原則的意思是:使用多個(gè)隔離的接口,比使用單個(gè)接口要好。還是一個(gè)降低類(lèi)之間的耦合度的意思,從這兒我們看出,其實(shí)設(shè)計(jì)模式就是一個(gè)軟件的設(shè)計(jì)思想,從大型軟件架構(gòu)出發(fā),為了升級(jí)和維護(hù)方便。所以上文中多次出現(xiàn):降低依賴(lài),降低耦合。
參考:https://realm.io/cn/news/donn-felker-solid-part-4/

5.迪米特法則(最少知道原則)(Demeter Principle)
為什么叫最少知道原則,就是說(shuō):一個(gè)實(shí)體應(yīng)當(dāng)盡量少的與其他實(shí)體之間發(fā)生相互作用,使得系統(tǒng)功能模塊相對(duì)獨(dú)立。

6.合成復(fù)用原則(Composite Reuse Principle)
原則是盡量使用合成/聚合的方式,而不是使用繼承。

模式分類(lèi)

創(chuàng)建型:?jiǎn)卫J健⒑?jiǎn)單工廠(chǎng)模式、工廠(chǎng)方法模式、抽象工廠(chǎng)模式、建造者模式、原型模式;
結(jié)構(gòu)型:代理模式、適配器模式、裝飾器模式、橋接模式、組合模式、享元模式、外觀(guān)模式;
行為型:觀(guān)察者模式、模板方法模式、命令模式、狀態(tài)模式、職責(zé)鏈模式、解釋器模式 、中介者模式、訪(fǎng)問(wèn)者模式、策略模式、備忘錄模式、迭代器模式;

創(chuàng)建者模式

1.單例模式(Singleton)

(1)理解:
保證一個(gè)類(lèi)僅有一個(gè)實(shí)例,并提供一個(gè)獲得該實(shí)例的方法(必須是靜態(tài)方法,通常用getInstance命名)

(2)類(lèi)圖:

單例模式.png

常使用的實(shí)現(xiàn)方法是這兩種,懶漢單例模式和DCL單例模式可參考,單例設(shè)計(jì)模式的N中Java實(shí)現(xiàn)方法

(3)栗子:
android中有很多系統(tǒng)級(jí)別的全局變量,如時(shí)間,輸入法,如InputMethodManager,賬戶(hù),狀態(tài)欄等,android中對(duì)這些都直接或者有些間接用到了單例模式。

(4)優(yōu)缺點(diǎn):
餓漢式:
優(yōu):線(xiàn)程安全,調(diào)用時(shí)反應(yīng)速度快,在類(lèi)加載的同時(shí)已經(jīng)創(chuàng)建好了一個(gè)靜態(tài)對(duì)象(創(chuàng)建的唯一對(duì)象);
缺:資源利用效率不高,可能該實(shí)例并不需要,但也被系統(tǒng)加載了,在一些場(chǎng)景下是無(wú)法使用的,比如,如果Single實(shí)例的創(chuàng)建依賴(lài)參數(shù)或配置文件,則在getInstance()之前必須調(diào)用某個(gè)方法來(lái)設(shè)置這些參數(shù),但在設(shè)置之前,可能已經(jīng)new了Single實(shí)例;static 內(nèi)部類(lèi)式:
優(yōu):線(xiàn)程安全,資源利用率高,不執(zhí)行g(shù)etInstance就不會(huì)被實(shí)例。
缺:第一次加載時(shí)反應(yīng)不快。

總之,單例模式,省去了new操作符,降低了系統(tǒng)內(nèi)存的使用頻率,減輕GC壓力;有些類(lèi)如交易所的核心交易引擎,控制著交易流程,如果該類(lèi)可以創(chuàng)建多個(gè)的話(huà),系統(tǒng)容易亂,使用單例模式,才能保證核心交易服務(wù)器獨(dú)立控制整個(gè)流程。

2.簡(jiǎn)單工廠(chǎng)模式

(1)理解
建立一個(gè)工廠(chǎng)類(lèi),對(duì)實(shí)現(xiàn)了同一接口的一些類(lèi)進(jìn)行實(shí)例的創(chuàng)建。

(2)類(lèi)圖

簡(jiǎn)單工廠(chǎng)模式.png

(3)栗子
出現(xiàn)了大量的產(chǎn)品需要?jiǎng)?chuàng)建,并且具有共同的接口時(shí)使用,但一般采用工廠(chǎng)方法模式。

(4)優(yōu)缺點(diǎn)
優(yōu):簡(jiǎn)單粗暴
缺:如果傳入的字符串有誤,不能正確創(chuàng)建對(duì)象,而且代碼比較臃腫,擴(kuò)展性不強(qiáng)。

3.工廠(chǎng)方法模式(Factory Method)

(1)理解

用于創(chuàng)建對(duì)象的接口,讓子類(lèi)決定實(shí)例化哪個(gè)類(lèi)。工廠(chǎng)方式模式使一個(gè)類(lèi)的實(shí)例化延遲到其子類(lèi)。
(2)類(lèi)圖

工廠(chǎng)方法模式.png

(3)栗子
如,Java的ThreadFactory。希望工廠(chǎng)與產(chǎn)品的種類(lèi)對(duì)客戶(hù)端保持透明,給客戶(hù)端提供一致的操作,另外一種是不同的工廠(chǎng)和產(chǎn)品可以提供客戶(hù)端不同的服務(wù)或功能。

(4)優(yōu)缺點(diǎn)
優(yōu):可派生多個(gè)產(chǎn)品,容易擴(kuò)展性,遵循單一職責(zé)、依賴(lài)倒置
缺:類(lèi)的創(chuàng)建依賴(lài)工廠(chǎng)類(lèi),也就是說(shuō),如果想要拓展程序,必須對(duì)工廠(chǎng)類(lèi)進(jìn)行修改,這違背了閉包原則,所以可以考慮使用抽象工廠(chǎng)模式。

4.抽象工廠(chǎng)模式(Abstract Factory)

(1)理解
創(chuàng)建多個(gè)工廠(chǎng)類(lèi),一旦需要增加新的功能,直接增加新的工廠(chǎng)類(lèi)就可以了,不需要修改之前的代碼。

(2)類(lèi)圖


UML-AbstractFactory.png

(3)栗子
如Java的List接口,軟件的換皮膚功能;需要一個(gè)接口可以提供一個(gè)產(chǎn)品族,且不必知道產(chǎn)品的具體種類(lèi)

(4)優(yōu)缺點(diǎn)
優(yōu):遵循單一職責(zé)、依賴(lài)倒置、開(kāi)閉原則,當(dāng)需要擴(kuò)展一個(gè)功能時(shí),只需做一個(gè)實(shí)現(xiàn)類(lèi),實(shí)現(xiàn)Sender接口,同時(shí)做一個(gè)工廠(chǎng)類(lèi),實(shí)現(xiàn)Provider接口,就OK了,無(wú)需去改動(dòng)現(xiàn)成的代碼。

注:
三種工廠(chǎng)模式的區(qū)別:
簡(jiǎn)單工廠(chǎng):用來(lái)生產(chǎn)同一等級(jí)結(jié)構(gòu)中的任意產(chǎn)品,對(duì)于增加新的產(chǎn)品,無(wú)能為力。
工廠(chǎng)方法:用來(lái)生產(chǎn)同一等級(jí)結(jié)構(gòu)中的固定產(chǎn)品,支持增加任意產(chǎn)品。
抽象工廠(chǎng):用來(lái)生產(chǎn)不同產(chǎn)品族(由不同產(chǎn)品組合成的一套產(chǎn)品)的全部產(chǎn)品,對(duì)于增加新的產(chǎn)品,無(wú)能為力;支持增加產(chǎn)品族。

參考:抽象工廠(chǎng)模式詳解

5.建造者模式(Builder)

(1)理解
將一個(gè)復(fù)雜對(duì)象的構(gòu)建和它的表示分離,使得同樣的創(chuàng)建過(guò)程可以創(chuàng)建不同的表示。
工廠(chǎng)類(lèi)模式提供的是創(chuàng)建單個(gè)類(lèi)的模式,而建造者模式則是將各種產(chǎn)品集中起來(lái)進(jìn)行管理,用來(lái)創(chuàng)建復(fù)合對(duì)象,所謂復(fù)合對(duì)象就是指某個(gè)類(lèi)具有不同的屬性,其實(shí)建造者模式就是前面抽象工廠(chǎng)模式和最后的Test結(jié)合起來(lái)得到的。
(2)類(lèi)圖

UML-Builder.png

或許,《Effective Java》的例子更好,遇到多個(gè)構(gòu)造參數(shù)時(shí)要考慮用構(gòu)建器(Builder模式):

class NutritionFacts {
    private final int servingSize;
    private final int servings;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;
    public static class Builder {
        //對(duì)象的必選參數(shù)
        private final int servingSize;
        private final int servings;
        //對(duì)象的可選參數(shù)的缺省值初始化
        private int calories = 0;
        private int fat = 0;
        private int carbohydrate = 0;
        private int sodium = 0;
        //只用少數(shù)的必選參數(shù)作為構(gòu)造器的函數(shù)參數(shù)
        public Builder(int servingSize,int servings) {
            this.servingSize = servingSize;
            this.servings = servings;
        }
        public Builder calories(int val) {
            calories = val;
            return this;
        }
        public Builder fat(int val) {
            fat = val;
            return this;
        }
        public Builder carbohydrate(int val) {
            carbohydrate = val;
            return this;
        }
        public Builder sodium(int val) {
            sodium = val;
            return this;
        }
        public NutritionFacts build() {
            return new NutritionFacts(this);
        }
    }
    private NutritionFacts(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        calories = builder.calories;
        fat = builder.fat;
        sodium = builder.sodium;
        carbohydrate = builder.carbohydrate;
    }
}
//使用方式
public static void main(String[] args) {
    NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100)
        .sodium(35).carbohydrate(27).build();
    System.out.println(cocaCola);
}

(3)栗子
android中大量的使用對(duì)話(huà)框組件,它的調(diào)用方法就是構(gòu)建,拼接,表示。

Android-Builder.jpeg

Builder通過(guò)setTitle(),setMessage(),setIcon()等方法在create()中構(gòu)造出一個(gè)AlertDialogInstance對(duì)象。
然后客戶(hù)可以把把AlertDialogInstance對(duì)象show出去。

附: Android用建造者模式實(shí)現(xiàn)一個(gè)新功能引導(dǎo)頁(yè)

(4)優(yōu)缺點(diǎn)
優(yōu):復(fù)用對(duì)象,避免不斷new構(gòu)造者增加開(kāi)銷(xiāo);將很多功能集成到一個(gè)類(lèi)里,創(chuàng)造出比較復(fù)雜的東西。

6.原型模式

(1)理解
用原型實(shí)例指定創(chuàng)建對(duì)象的種類(lèi),并且通過(guò)拷貝這些原型創(chuàng)建新的對(duì)象。

(2)類(lèi)圖

注:克隆操作分深拷貝和淺拷貝,淺拷貝說(shuō)白了就是把原對(duì)象所有的值和引用直接賦給新對(duì)象。深拷貝則不僅把原對(duì)象的值賦給新對(duì)象,而且會(huì)把原對(duì)象的引用對(duì)象也重新創(chuàng)建一遍再賦給新對(duì)象。

(3)栗子
如Java的Cloneable接口。
使用場(chǎng)景:a.對(duì)象的創(chuàng)建非常復(fù)雜,可以使用原型模式快捷的創(chuàng)建對(duì)象。b.在運(yùn)行過(guò)程中不知道對(duì)象的具體類(lèi)型,可使用原型模式創(chuàng)建一個(gè)相同類(lèi)型的對(duì)象,或者在運(yùn)行過(guò)程中動(dòng)態(tài)的獲取到一個(gè)對(duì)象的狀態(tài)。

(4)優(yōu)缺點(diǎn)
缺:每個(gè)原型的子類(lèi)都必須實(shí)現(xiàn)Cloneable接口,這個(gè)實(shí)現(xiàn)起來(lái)有時(shí)候比較困難。

詳細(xì):原型模式詳解(clone方法源碼的簡(jiǎn)單剖析)

持續(xù)更新,整理得不對(duì)的地方,還望指正!

參考:
1.Java之美[從菜鳥(niǎo)到高手演變]之設(shè)計(jì)模式-終點(diǎn)
2.Android設(shè)計(jì)模式系列-謙虛天下
3.設(shè)計(jì)模式系列-Tony Chen
4.設(shè)計(jì)模式詳解-左瀟龍
5.設(shè)計(jì)模式UML類(lèi)圖

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,517評(píng)論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,087評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 177,521評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,493評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,207評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,603評(píng)論 1 325
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,624評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,813評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,364評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,110評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,305評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,874評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,532評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,953評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,209評(píng)論 1 291
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,033評(píng)論 3 396
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,268評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式匯總 一、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,960評(píng)論 1 15
  • 一、設(shè)計(jì)模式的分類(lèi) 總體來(lái)說(shuō)設(shè)計(jì)模式分為三大類(lèi): 創(chuàng)建型模式,共五種:工廠(chǎng)方法模式、抽象工廠(chǎng)模式、單例模式、建造者...
    RamboLI閱讀 767評(píng)論 0 1
  • 面向?qū)ο笤O(shè)計(jì)的五大原則 單一職責(zé)原則(SRP) 一個(gè)類(lèi)應(yīng)該僅有一個(gè)職責(zé)。 開(kāi)放封閉原則(OCP) 對(duì)擴(kuò)展開(kāi)放,...
    LiuHDme閱讀 1,476評(píng)論 0 3
  • 一、設(shè)計(jì)模式的分類(lèi) 總體來(lái)說(shuō)設(shè)計(jì)模式分為三大類(lèi): 創(chuàng)建型模式,共五種:工廠(chǎng)方法模式、抽象工廠(chǎng)模式、單例模式、建造者...
    lichengjin閱讀 905評(píng)論 0 8
  • 原文鏈接:http://blog.csdn.net/zhangerqing http://www.cnblogs....
    孤獨(dú)雜貨鋪閱讀 1,526評(píng)論 0 3