【朝花夕拾】設計模式之裝飾器模式

来源:https://www.cnblogs.com/edison0621/archive/2019/03/30/10628782.html
-Advertisement-
Play Games

裝飾器模式簡介 裝飾器模式是動態的向一個對象添加新的功能,並且保持其類方法簽名的完整性,換言之,其方法及繼承結構將不會被改變。這種模式一種結構型模式,是對現有類的包裝。這種模式,比生成子類更加靈活,更重要的是,裝飾者模式裝飾的是特定的行為或者或是職責,也沒有必要通過子類實現。 在日常生活中,裝飾器模 ...


 

裝飾器模式簡介

裝飾器模式是動態的向一個對象添加新的功能,並且保持其類方法簽名的完整性,換言之,其方法及繼承結構將不會被改變。這種模式一種結構型模式,是對現有類的包裝。這種模式,比生成子類更加靈活,更重要的是,裝飾者模式裝飾的是特定的行為或者或是職責,也沒有必要通過子類實現。

在日常生活中,裝飾器模式的場景更多是的打扮了,一個妹子,嫌棄自己的臉長得不夠漂亮,想換張臉很困難,但是化化妝還是很容易的(當然了,化妝也分男女的,此處指的是女士化妝,大老爺們有啥好化的,還不如收拾山河,收復釣魚島),加點粉底啊,塗點腮紅啊,塗眼影,畫眼線,再加點口紅,哇塞,一個大美女就這樣誕生了,這就是打扮的力量,這就是裝飾的力量,這也是愛美的力量。寫到這裡我突然想到一句話就是,清水出芙蓉,天然去雕飾,當自然不能使之完美時,藝術使之完美。

裝飾器模式就是,在一個已經先天不足或者未來有可能需要擴展的場景中,修改代碼將是一件工作量十分巨大的事情,也是危險繫數比較高的事情,我們需要以一個比較經濟、安全的方式來解決這個問題,可以認為是從周邊方式、從外圍方式來解決問題。

這個例子也告訴我們,生活處處是學問,紙上得來終覺淺,覺知此時要躬行,當你看到這篇文章的時候,不必太過糾結於其定義或者UML,你可以更多的去類比你的生活,這樣你會更快更深刻的獲取知識。

裝飾器模式UML類圖

zhuangshiqi

小提醒

裝飾器類繼承並依賴於更抽象一級的IWoman介面,在地位上與Face、Clothes一致
裝飾器類對IWoman介面的方法進行了包裝,隱隱約約有模板方法模式的影子

範例

以下範例,會使用前面所說的女人喜歡打扮使用打扮方式解決自然問題或者說更進一層樓的問題,女人的打扮有方方面面的,不過最常見也就是化妝和穿衣,所以此處使用這兩個裝扮方式予以Coding。

抽象介面:

   1:  public interface IWoman
   2:  {
   3:      void Attire();
   4:  }

 

臉部打扮

   1:  public class Face : IWoman
   2:  {
   3:      public void Attire()
   4:      {
   5:          Console.Write("那些年還不會打扮,擦點自己也不知道是什麼的粉");
   6:      }
   7:  }

穿衣打扮

   1:  public class Clothes : IWoman
   2:  {
   3:      public void Attire()
   4:      {
   5:          Console.Write("那些年還不會打扮,穿點屌絲裝");
   6:      }
   7:  }

裝飾器抽象類

   1:  public abstract class RougeDecorator : IWoman
   2:  {
   3:      protected IWoman woman;
   4:   
   5:      public RougeDecorator(IWoman woman)
   6:      {
   7:          this.woman = woman;
   8:      }
   9:   
  10:      public virtual void Attire()
  11:      {
  12:          this.woman.Attire();
  13:      }
  14:  }

臉部增加裝飾

   1:  public class FaceDecorator : RougeDecorator
   2:  {
   3:      public FaceDecorator(IWoman woman) : base(woman)
   4:      {
   5:      }
   6:   
   7:      public override void Attire()
   8:      {
   9:          this.woman.Attire();
  10:          Console.WriteLine("這些年學會了打扮,還要繼續化妝,塗眼影,畫眼線");
  11:      }
  12:  }

穿衣增加裝飾

   1:  public class ClothesDecorator : RougeDecorator
   2:  {
   3:      public ClothesDecorator(IWoman woman) : base(woman)
   4:      {
   5:      }
   6:   
   7:      public override void Attire()
   8:      {
   9:          this.woman.Attire();
  10:          Console.WriteLine("這些年學會了打扮,打底褲,包臀裙,上衣也要換一下,名牌穿起,還要再戴個帽子,回頭率必須杠杠的");
  11:      }
  12:  }

調用

   1:  class Program
   2:  {
   3:      static void Main(string[] args)
   4:      {
   5:          IWoman womanFace = new Face();
   6:          IWoman womanDress = new Clothes();
   7:   
   8:          IWoman womanFaceDecorator = new FaceDecorator(womanFace);
   9:          IWoman womanClothesDecorator = new ClothesDecorator(womanDress);
  10:   
  11:          womanFaceDecorator.Attire();
  12:          womanClothesDecorator.Attire();
  13:   
  14:          Console.WriteLine("----------------------------------------------------");
  15:          Console.WriteLine("完美女人出現了");
  16:          Console.WriteLine("既然完美女人已經出現了,那就抓緊娶回家,然後把裝飾器給關掉");
  17:          Console.WriteLine("卧槽,貌似有點難關呀,該死的裝飾器");
  18:          Console.WriteLine("難不倒我,把你化妝品換成路攤貨,越塗越難看,哈哈,難不倒我程式員");
  19:   
  20:          Console.ReadLine();
  21:      }
  22:  }

調用結果如下圖所示

1553947981(1)

 

裝飾器模式優缺點

優點:

  • 很好的利用了開閉原則,裝飾類和被裝飾類可以獨立發展,不會相互耦合。
  • 裝飾模式是繼承的一個替代模式,可以動態擴展一個實現類的功能

缺點:

  • 裝飾模式會使得業務及代碼變得複雜

裝飾器模式使用場景思考

裝飾器模式,從某種角度上說,可能更適合用於對已經成型的業務進行修改的場景,不管是用於動態擴展,還是動態移除,裝飾器都能很方便的勝任對對象的修改操作。另外就是,繼承也可以解決類似問題,但是裝飾器可以更好的擴展,因為,我們一般解決的是特定對象的特定行為,而不會對整個對象進行修改,這樣子跟大型重構沒有什麼區別。所以,特定場景的修改,裝飾器來的更快,更簡單,更有效率,沒有必要興師動眾。


以上為本篇文章的主要內容,希望大家多提提意見,如果喜歡記得點個贊哦


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

-Advertisement-
Play Games
更多相關文章
  • 項目簡介: 網上招聘系統的設計與實現,包含倆個角色:個人和公司角色。本系統結構如下: 個人角色(1)首頁:顯示個人可以申請職位的公司信息,實現了查詢、申請職位功能 (2)個人信息修改:實現了對個人信息(簡歷)的修改 (3)下載簡歷:實現對簡歷的下載 (4)發佈簡歷 (5)撤銷簡歷 (6)消息通知:實 ...
  • 題目鏈接 題意 其實就是求 $$\sum\limits_{i=1}^n\sum\limits_{j=1}^ngcd(i,j)$$ 思路 建議先看一下此題的一個弱化版 推一下式子 $$\sum\limits_{i=1}^n\sum\limits_{j=1}^ngcd(i,j)$$ $$= \sum\l ...
  • 項目簡介: 網上體育商城的主要功能包括:前臺用戶登錄退出、註冊、線上購物、修改個人信息、後臺商品管理等等。本系統結構如下: (1)商品瀏覽模塊: 首頁瀏覽最新上市商品,按銷量排行顯示商品 實現根據商品名稱搜索商品信息 實現根據商品分類瀏覽商品 (2)登錄、註冊: 購物前需要登錄,如果沒有賬號則可以先 ...
  • 內部類 什麼是內部類? 將一個類A定義在另一個類B裡面,裡面的那個類A就稱為內部類,B則稱為外部類 成員內部類:定義在類中方法外的類 定義格式示例: 在描述事物時,若一個事物內部還包含其他事物,就可以使用內部類這種結構。 訪問特點: 內部類可以直接訪問外部類的成員,包括私有成員 外部類要訪問內部類的 ...
  • 第一個Python與Django的相容關係 1、python2.7支持到2020年 2、Django2.0後均不再支持python2 3、Django2.0是最後一個支持Python3.4的版本 4.目前為止開發學習最好用Django2.1 第二個Django與MySQL的相容關係 1、Django ...
  • 題意 "題目鏈接" Sol 線性基+線段樹分治板子題。。 調起來有點自閉。。 cpp include define fi first define se second define pb push_back define bit bitset using namespace std; const i ...
  • 老牌.NET控制項服務商,專註微軟.Net平臺的表示層與內容管理控制項 ...
  • Private Sub DS按鈕1_ButtonClick(Sender As Object) Handles DS按鈕1.ButtonClick Dim T As New Threading.Thread(AddressOf Doit) T.IsBackground = True T.Start(... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...