設計模式之裝飾者模式(一)

来源:https://www.cnblogs.com/dimple91/archive/2019/04/03/10647097.html
-Advertisement-
Play Games

經過前兩個模式的學習,是不是對設計模式有了進一步的認識了呢,現在,我們繼續沖鴨。 本章可以稱為“給愛用繼承的人一個全新的設計眼界”。這裡我們即將再度探討典型的繼承濫用問題,我們將學到如何使用對象組合的方式,做到在運行時裝飾類。為什麼呢?一旦熟悉了裝飾的技巧,你將能夠在不修改任何底層代碼的情況下,給對 ...


經過前兩個模式的學習,是不是對設計模式有了進一步的認識了呢,現在,我們繼續沖鴨。

本章可以稱為“給愛用繼承的人一個全新的設計眼界”。這裡我們即將再度探討典型的繼承濫用問題,我們將學到如何使用對象組合的方式,做到在運行時裝飾類。為什麼呢?一旦熟悉了裝飾的技巧,你將能夠在不修改任何底層代碼的情況下,給對象賦予新的職責。

之前我們見識了鴨子的各個表現會飛、會游泳、會叫、會跳;也看過了氣象臺實時更新的能力,在看板里把數據更新;接下來我們一起來喝下咖啡,體驗一把喝咖啡的樂趣。咖啡店裡的生意太好了,需要升級現有的產品,所以店主準備更新訂單系統,以此來滿足店內各位顧客。

先來看一張圖,這是原先的店內設計

看出什麼來了嗎?沒錯,就是各個類來滿足對咖啡的不同要求。那麼,如果店內產品需要升級,比如購買咖啡時,想加入各種調料,例如:蒸奶,豆漿,摩卡或者覆蓋奶泡。咖啡店根據不同的調料,收取不同的費用,所以有多少種調料,就有多少種類,是這個意思沒錯吧。然後,就會很悲劇,請看下麵擴展調料之後的圖


我的天,這是啥,這要是寫了這樣的項目,還不是分分鐘要被哭死,維護這麼多的類。

認識裝飾者模式

當前遇到的問題就是:類數量爆炸、設計死板、以及基類加入的新功能並不適用於所有的子類。

所以,裝飾者要隆重出場。在這裡要採用不一樣的做法:我們要以飲料為主體,然後再運行試以調料來“裝飾”(decorate)飲料。加入某個顧客想要摩卡和奶泡深培咖啡,那麼具體的做法就可以是:

  1. 拿一個深培咖啡(DarkRoast)對象
  2. 以摩卡(Mocha)對象裝飾它
  3. 以奶泡(Whip)對象裝飾它
  4. 調用cost方法,並依賴委托(delegate)將調料的價錢加上去

以裝飾者構造飲料訂單

為了讓讀者更加清晰的瞭解,小編在這裡直接給了書中的圖來表示

根據以上信息,我們知道

  • 裝飾者和被裝飾對象有相同的超類型
  • 你可以用一個或多個裝飾者包裝一個對象
  • 既然裝飾者和被裝飾對象有相同的超類型,所以在任何需要原始對象(被包裝的)的場合,可以用裝飾過的對象代替它
  • 裝飾者可以在所委托被裝飾者的行為之前/或之後,加上自己的行為,以達到特定的目的---關鍵點
  • 對象可以在任何時候被裝飾,所以可以再運行時動態地、不限量地用你喜歡的裝飾者來裝飾對象

來看看裝飾者模式的定義吧。

定義裝飾者模式

裝飾者模式動態地將責任附加到對象上。若要擴展功能呢,裝飾者提供了比繼承更有彈性的替代方案。

那麼我們如何在現實中實際應用裝飾者模式呢,先來看看根絕角色來分配的類圖

裝飾我們的飲料

從上面的類圖,看出什麼了嗎?想到我們的飲料的類圖怎麼畫了沒呢。接下來,就讓我們照貓畫虎,來畫一個屬於我們的裝飾類類圖

鑒於之前有讀者反映,說出現篇幅過長的情況。小編自己也曾疑惑,到底怎麼更好地控制篇幅。所以,從今天開始,小編在力爭保持思路一慣性的條件下,模塊分的更細緻,篇幅更加適中,讓碎片化時間得到充分的利用。

所以,今天的學習就先到這裡啦。下一篇,會針對類圖進行實際的代碼編寫以及其他補充性的情況。大家也可以先根據代碼,在偽代碼的世界里實踐下,也利於咱們下次的編碼實戰。

PS:代碼已經上傳,需要查看的朋友點擊此處HeadFirstDesign

愛生活,愛學習,愛感悟,愛挨踢

image


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

-Advertisement-
Play Games
更多相關文章
  • 最近有個需求,是用vue做的頁面,其中嵌入了一個tinymce編輯器,編輯器設置了自動調整高度,也就是說編輯器中內容越多,高度就會自動撐高 我們需要再頁面最下方放一個保存按鈕,保存按鈕必須固定在屏幕下方,本來想用position:fixed這種簡單方法,但是業務比較特殊,不能這麼用,無奈只能用pos ...
  • 前言 鎖,顧名思義就是鎖住一些資源,當只有我們拿到鑰匙的時候,才能操作鎖住的資源。在我們的Java,資料庫,還有一些分散式的環境中,總是充斥著各種各樣的鎖讓人頭疼,例如“公平鎖”、“自旋鎖”、“讀寫鎖”、“分散式鎖”等等。 其實真實的情況是,鎖並沒有那麼多,很多概念只是從不同的功能特性,設計,以及鎖 ...
  • 一般情況下,在我們做訪問許可權管理的時候,會把用戶的正確登錄後的基本信息保存在Session中,以後用戶每次請求頁面或介面數據的時候,拿到 Session中存儲的用戶基本信息,查看比較他有沒有登錄和能否訪問當前頁面。 Session的原理,也就是在伺服器端生成一個SessionID對應了存儲的用戶數據 ...
  • 定義 提供了一個統一的介面,用來訪問子系統中一群介面 適用場景 詳解 外觀模式,主要理解外觀。通俗一點可以認為這個模式是將子系統封裝到一起,提供給應用的層面就提供一個方法。不直接由應用層直接訪問子系統。 下麵我們看看ibatis的源碼來具體理解外觀模式。 上述代碼其實是完成一個創建MetaObjec ...
  • 簡單工廠模式概述 簡單工廠模式的結構與實現 結構: 實現 1 abstract class Product 2 { 3 public void MethName() 4 { 5 //公共方法的實現 6 } 7 public abstract void MethodDiff(); 8 //聲明抽象業務 ...
  • 定義: 指原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。不需要知道任何創建的細節,不調用構造函數適用場景: 詳解: 接下來我們分下麵幾部分講解: 1.原型模式的核心 其實很簡單,就是實現Cloneable介面,然後重寫clone()方法。上面我們已經說過 ,當你在上面的適用場景中的時 ...
  • 模式的誕生與定義 -Context(模式可適用的前提條件)-Theme或Problem(在特定條件下要解決的目標問題)-Solution(對目標問題求解過程中各種物理關係的記述) 設計模式的分類 Gof設計模式 創建型模式(關註對象的創建過程,對類的實例化過程進行抽象,描述如何將對象的創建和使用分離 ...
  • 概念重覆請求是指一個請求因為某些原因被多次提交,場景簡述如下:1)用戶快速多次點擊按鈕2)Nginx失敗重試機制3)服務框架失敗重試機制4)MQ消息重覆消費5)第三方支付支付成功後,因為異常原因導致的多次非同步回調; 冪等性是指同樣的請求參數,多次請求返回的結果相同。一般是因為重覆請求導致的重覆操作等 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...