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

来源:http://www.cnblogs.com/zhenbianshu/archive/2017/08/21/7406572.html
-Advertisement-
Play Games

PHP程式員閱讀Java語言實現設計模式的書,然後用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 個簡化版,就自己查資料結合自己的理解來總結了。

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

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Struts2.5 struts是開源框架。使用Struts的目的是為了幫助我們減少在運用MVC設計模型來開發Web應用的時間。如果我們想混合使用Servlets和JSP的優點來建立可擴展的應用,struts是一個不錯的選擇。 Struts 是Apache軟體基金會(ASF)贊助的一個開源項目。它最 ...
  • 上面的代碼實現的只是簡單而繁瑣的一種,後面的代碼會一直重覆,因此並沒有寫下去,後面的是我看視頻附帶的代碼,我也附上,較我寫的完整一些 ...
  • 1 1、請求周期 2 url> 路由 > 函數或類 > 返回字元串或者模板語言? 3 4 Form表單提交: 5 提交 -> url > 函數或類中的方法 6 - .... 7 HttpResponse('....') 8 render(request,'index.html') 9 redirec ...
  • 簡史 官方文檔說的很清楚,商戶已有H5商城網站,用戶通過消息或掃描二維碼在微信內打開網頁時,可以調用微信支付完成下單購買的流程。 當然,最近微信支付平臺也加入了純H5支付,也就是說用戶可以在微信以外的手機瀏覽器請求微信支付的場景喚起微信支付。 當然,今天的主角是微信公眾號支付,其實也不一定非在公眾號 ...
  • 最近接手的 Apache HUE 項目性能出現了問題,線上經常出現響應時間過長或因為時間過長而無法服務等問題.老大讓我準備弄個性能分析工具,便於追蹤和分析平臺當前的瓶頸出現在哪裡. 那就搞起吧!先從代碼性能分析入手.本篇博客分享的也是代碼層面的性能分析. 之前用過的就有 插件. 這款插件主要可以用來 ...
  • AJAX = Asynchronous JavaScript and XML(非同步的 JavaScript 和 XML)。 Ajax作用:是用JavaScript向伺服器發送非同步請求,然後伺服器給出響應,然後以XML格式的文件返回給瀏覽器端! 非同步:當瀏覽器向伺服器發送請求的時候,不是整個頁面刷新, ...
  • <?php//簡單函數function show(){ echo "hello"; }show(); //有參數的函數function show($a){ echo "$a"; }show("world"); //有返回值的函數 function show(){ return "小V,你好!"; } ...
  • /** * 文檔註釋只定義在三個地方 : 類、常量、方法上 * 在類上定義文檔註釋用來說這個類設計及其解決問題等相關描述信息 * @author 作者 * @version 1.0 21/08/17 版本號 修改的版本號和最後修改 *的時間 * @see java.lang.String 參考的類, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...