設計模式,Let's “Go”! (上)


 

前言

最近讀了《Head First 設計模式》,每天早上看一章,學習一個設計模式,做些筆記,然后晚上抽空用剛學習的 Go 語言實現一下。半個月下來書讀完了,留下了一些筆記,寫博客總結一下。

書中的例子都是 Java 寫的,但幾乎沒使用 Java 語言的特性,很容易看懂。對於我來說,就是一個 PHP 開發工程師,讀了一本 用 Java 語言實現設計模式的書,然后用 Go 寫了一遍。。。=_=

本文為每個設計模式只分配了一小節,總結一下設計模式的概念和特點以及適用場景,並介紹了自己用代碼實現時的列舉的例子,用現實生活中的事物對比加深一下記憶 ( 代碼實現中所有的例子都是自己原創的,有牽強的部分,不要介意)。每個模式篇幅不大,可以給新人入門,給了解過設計模式的人作為速查。

文章經常被人爬,而且還不注明原地址,我在這里的更新和糾錯沒法同步,這里注明一下原文地址:http://www.cnblogs.com/zhenbianshu/p/7406572.html  以防誤人子弟。

放上 Go 實現設計模式的 源碼地址:DesignPattern-枕邊書-Github ,偶有更新,歡迎 star。OK,正文開始。


策略模式(Strategy)

介紹

策略模式: 將算法或操作抽象成實現共同接口、可以被替換的類,實現邏輯和具體算法的解耦。

  • 將各種行為抽象成算法,封裝算法為對象;
  • 算法實現共同接口,調用者調用時不考慮算法具體實現,調用接口方法即可;
  • 調用者可隨時替換此算法對象;

場景

  • 多個方法擇一使用,且他們會被隨時替換;
  • 方法沒有共性,使用繼承會有大量重寫,使用接口會有大量重復使用;

實現

  1. 兩個算法: 冒泡排序和快速排序;
  2. 抽象冒泡排序和快速排序為算法對象,實現算法接口,擁有 used() 被使用方法;
  3. 計算器計算時不用理會是什么算法,調用 used() 即可;

觀察者模式(Observer)

介紹

觀察者模式:主題主動向觀察者推送變化,解決觀察者對主題對象的依賴。

  • 觀察者實現被通知接口,並在主題上注冊,主題只保存觀察者的引用,不關心觀察者的實現;
  • 在主題有變化時調用觀察者的通知接口來通知已注冊的觀察者;
  • 通知方式有(主題變化時將變化數據推送給觀察者)和(主題只告知變化,觀察者主動來拉取數據);

場景

  • 一個主題,多個觀察者,主題的任何變動,觀察者都要第一時刻得到;
  • 觀察者獲取主題變化困難,定時不及時,輪詢消耗大;
  • 觀察者可以隨時停止關注某主題;

實現

  1. 張三和李四是記者,他們需要及時了解城市發生的新聞;
  2. 張三和李四在電視台注冊了自己的信息;
  3. 城市發生了新聞,電視台遍歷注冊信息,通知了張三和李四;
  4. 李四退休了,在電視台注銷了自己的信息;
  5. 城市又發生了新聞,電視台只通知了張三;

裝飾者模式(Decorator)

介紹

裝飾者模式:包裝一個對象,在被裝飾對象的基礎上添加功能

  • 裝飾者與被裝飾對象擁有同一個超類,裝飾者擁有被裝飾對象的所有外部接口,可被調用,外界無法感知調用的是裝飾者還是被裝飾者;
  • 裝飾者需要被裝飾者作為參數傳入,並在裝飾者內部,在被裝飾者實現的基礎上添加或修改某些功能后,提供同被裝飾者一樣的接口;
  • 裝飾者也可被另一個裝飾者裝飾,即嵌套裝飾;
  • 裝飾者是一群包裝類,由於裝飾的復雜性,會多出很多個裝飾者小類;

場景

  • 對象需要動態地添加和修改功能;
  • 功能改變后不影響原對象的使用;

實現

  1. 在商店內,花作為被裝飾者對象、紅絲帶和盒子作為花的裝飾者;
  2. 花、紅絲帶、盒子有共同的超類“商品”,他們都能被賣掉;
  3. 我們可以在紅絲帶裝飾過花后,再用盒子再包裝一次;
  4. 包裝后的花,顧客買時也不會受到任何影響;

工廠模式(Factory)

介紹

工廠模式: 顧名思義,工廠模式是對象的生產器,解耦用戶對具體對象的依賴。

  • 實現依賴倒置,讓用戶通過一個產品工廠依賴產品的抽象,而不是一個具體的產品;
  • 簡單工廠模式:接收參數並根據參數創建對應類,將對象的實例化和具體使用解耦;
  • 抽象工廠模式:將工廠抽象出多個生產接口,不同類型的工廠調用生產接口時,生產不同類型的對象;
  • 簡單工廠常配合抽象工廠一起使用;

場景

  • 根據不同條件需求不同的對象;
  • 對象實例化的代碼經常需要修改;

實現

  1. 簡單工廠:向鞋廠內傳入不同的類型(布制),鞋廠會生產出不同類型的鞋子(布鞋);
  2. 抽象工廠:有兩座鞋廠:李寧鞋廠、Adidas鞋廠,他們能生產對應各自品牌的鞋子;
  3. 搭配使用:向不同的抽象工廠(李寧)傳入不同的類型(運動類型),會生產出對應品牌對應類型的鞋子(李寧運動鞋);

單例模式(Singleton)

介紹

單例模式:保證同一個類全局只有一個實例對象;

  • 在第一次實例化后會使用靜態變量保存實例,后續全局使用此靜態變量;
  • 一般將構造方法私有化,構造方法添加 final 關鍵字無法被重寫,添加一個類靜態方法用於返回此實例;
  • 在多線程時應該考慮並發問題,防止兩次調用都被判定為實例未初始化而重復初始化對象;

場景

  • 全局共享同一個實例對象(數據庫連接等);
  • 某一處對此對象的更新全局可見;

實現

  1. 利用 Go 中包的可見性規則來隱藏對象的實例化權限;
  2. 使用包變量保存實例對象,獲取實例時判斷是否已實例化,如為nil,實例化對象並返回,如有值,直接返回值;
  3. 待用鎖實現 Go routine 並發時的問題;

命令模式(Command)

介紹

命令模式:將一個命令封裝成對象,解耦命令的發起者和執行者。

  • 命令對象實現命令接口(excute[、undo]),命令發起者實例化命令對象,並傳遞此對象,並不關心此對象由誰執行;
  • 命令執行者只負責調用命令對象的執行方法即可,不關心對象是由誰生成的;
  • 與策略模式不同之處:策略模式是通過不同的算法做同一件事情(例如排序),而命令模式則是通過不同的命令做不同的事情;

場景

  • 命令發起者與執行者無法直接接觸;
  • 命令需要撤銷功能,卻不易保存命令執行狀態信息時;

實現

  1. 指揮官創建了一個“從樹下跑到草地上”的命令;
  2. 命令被分配給張三執行,張三作為軍人,接到命令后不管命令的具體內容,而是直接調用命令的執行接口執行;
  3. 指揮官發布了撤銷指令,張三又從草地上跑到了樹下;

適配器模式(Adapter)

介紹

適配器模式:包裝對象提供一個接口,以適配調用者

  • 適配器通過一個中間對象,封裝目標接口適應調用者調用;
  • 調用者調用此適配器,以達到調用目標接口的目的;
  • 適配器模式與裝飾者模式的不同之處:適配器模式不改變接口的功能,而裝飾者會添加或修改原接口功能;

場景

  • 提供的接口與調用者調用的其他的接口都不一致;
  • 為一個特殊接口修改調用者的調用方式得不償失;

實現

  1. 張三是個正常人,他能通過說話直接地表達自己;
  2. 李四是個聾啞人,他沒法直接表達自己,但他會寫字;
  3. 筆記本作為一個適配器,用筆記本“包裝”了李四之后,當李四需要表達自己想法時,調用筆記本的“表達”功能,筆記本再調用李四“寫字”的方法;

外觀模式(Facade)

介紹

外觀模式:通過封裝多個復雜的接口來提供一個簡化接口來實現一個復雜功能。

  • 外觀模式是通過封裝多個接口來將接口簡單化
  • 外觀模式不會改變原有的多個復雜的單一接口,這些接口依然能被單獨調用,只是提供了一個額外的接口;
  • 外觀模式與適配器模式的不同之處:外觀模式是整合多個接口並添加一個簡化接口,適配器是適配一個接口;

場景

  • 實現某一功能需要調用多個復雜接口;
  • 經常需要實現此功能;

實現

  1. 正常的沖咖啡步驟是:磨咖啡豆、燒開水、倒開水攪拌咖啡。
  2. 我們經常需要直接沖咖啡,而不是使用單一步驟,每次喝咖啡時調用三個方法很麻煩;
  3. 封裝三個接口,額外提供一個 “沖咖啡” 的方法,需要喝咖啡時只需要調用一次沖咖啡方法即可;

小結

《Head First 設計模式》這書真心不錯,例子很輕松,給人很多時間和空間來思考,同時介紹模式時使用結合故事,層層深入的方法,讓人印象很深刻,推薦。

書中詳細介紹了 14 個基礎設計模式,還有 9 個簡化版,就自己查資料結合自己的理解來總結了。

本系統准備寫三篇,敬請期待中下篇。

關於本文有什么問題可以在下面留言交流,如果您覺得本文對您有幫助,可以點擊下面的 推薦 支持一下我。博客一直在更新,歡迎 關注


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM