裝飾模式(Decorator Pattern)

来源:https://www.cnblogs.com/ygsworld/archive/2019/05/11/10848828.html
-Advertisement-
Play Games

裝飾模式概述 定義:動態地給一個對象增加一些附屬的職責。 裝飾裝飾,自然的理解就是在原有物品的基礎上,增加一些別的東西,讓它變得更令人滿意。且裝飾模式是在不改變對象本身的基礎上就行額外的增加,更加靈活。 比如買房,首先買的是個空房,隨後我們會放進去傢具,和各種生活中要用的東西,讓這個家變得更有家的味 ...


  • 裝飾模式概述

定義:動態地給一個對象增加一些附屬的職責。

裝飾裝飾,自然的理解就是在原有物品的基礎上,增加一些別的東西,讓它變得更令人滿意。且裝飾模式是在不改變對象本身的基礎上就行額外的增加,更加靈活

比如買房,首先買的是個空房,隨後我們會放進去傢具,和各種生活中要用的東西,讓這個家變得更有家的味道,這就是裝飾。我們也沒有改變房子的結構。下次,也可以重新對傢具進行佈局,變成另外的風格

  • 裝飾模式的結構和實現

Component(抽象構件): (空房):具體構件和抽象裝飾類的父類,聲明瞭具體構件中的業務方法

1 abstract class Component
2 {
3     public abstract void Operation();
4 }

ConcreteComponent(具體構件類):(剛買的北京二環內的一套房)抽象構件類的子類,用於定義具體的構件對象,實現在抽象構件中聲明的方法。裝飾類可以為它增加額外職責

1 class ConcreteComponent : Component
2 {
3     public override void Operation()
4     {
5         //功能實現
6     }

Decorator(抽象裝飾類):(傢具城)抽象構件類的子類,用來給具體構件增加職責

 1 class Decorator :Component
 2 {
 3     private Component component;//抽象構件對象的引用
 4     
 5     public Decorator(Component component)
 6     {
 7         this.component = component;
 8     }
 9     
10     public override void Operation()
11     {
12         component.Operation();//調用原有業務方法
13     }
14 }

ConcreteDecorator(具體裝飾類):(桌子 椅子 電器 床.......)抽象裝飾類的子類,負責向構件增加新的職責

 1 class ConcreteDecorator :Decorator
 2 {
 3     public ConcreteDecorator(Component component ):base (component)
 4     {
 5     }
 6     
 7     public void AddedBehavir()
 8     {
 9         //新的業務方法
10     }
11     
12     public override void Operation()
13     {
14         base.Operation();//調用原有方法
15         AddedBehavir();//調用新的方法
16     }
17 }
  • 裝飾模式的應用

 現有一家咖啡店,可以根據客戶需求提供對應的咖啡。咖啡{  {濃縮咖啡(Espresso),25},{混合咖啡(House Blend),30},{重烘焙咖啡(Dark Roast),20}  }

配料{ {摩卡(Mocha),10} ,{奶泡(Whip),8 },{牛奶 (Milk),6} }

輸出 濃縮咖啡,摩卡,牛奶  41

分析:這就是個混合搭配的情況,只要你有錢,一種咖啡想搭配多少種配料都可以,那我們算算,3種咖啡,3種配料,一共可以搭配出多少種不同的飲料呢???不難算出,一種咖啡可以有8種(2^3)搭配,那麼3種咖啡共有24種。那麼這題寫出24種類不就行了。當然是可以的。用繼承,也是可以的。但是,由於自由搭配的情況,導致把全部情況寫出來是完全低效的。所以,飲料類可以作為抽象類,配料類作為裝飾類,使用裝飾模式。我們想想,咖啡和配料的搭配,無論是咖啡搭配配料,還是配料搭配咖啡,效果都是一樣的。但是,為了不影響咖啡類本身,我們是將配料類關聯咖啡類的,即將咖啡類的對象作為自己的成員變數。

Component(抽象構件):Coffee

1 abstract  class Coffee//飲料類
2 {    
3          public abstract  double Cost();
4          public abstract string Description();
5 }
View Code

ConcreteComponent(具體構件類):濃縮咖啡(Espresso)、混合咖啡(House Blend)、重烘焙咖啡(Dark Roast)

 1 class Espresso : Coffee //特濃咖啡(Espresso) vs 滴漏咖啡(Drip)  特濃咖啡的製作原理是讓熱水在高壓下流過一把壓得嚴嚴實實的細膩的咖啡粉,咖啡因濃度較高,有咖啡脂。
 2     {
 3         public override double Cost()
 4         {
 5             return 25;
 6         }
 7 
 8         public override string Description()
 9         {
10             return "濃縮咖啡";
11         }
12     }
13 class DarkRoast : Coffee //深培咖啡:按照美式分級,咖啡豆的烘焙由淺至深可分為八個階段。咖啡的味道主要取決於烘焙度,一般烘焙程度越深苦味越濃,烘焙程度越低,酸味就越高。
14     {
15         public override double Cost()
16         {
17             return 20;
18         }
19 
20         public override string Description()
21         {
22             return "深培咖啡";
23         }
24     }
25  class HouseBlend : Coffee //北美特別流行的黑咖啡,它屬於混合咖啡,配方因地而有所不同,但主要成分都有50%以上的哥倫比亞咖啡豆.可以翻譯為家常咖啡。
26     {    
27         public override double Cost()
28         {
29             return 30;
30         }
31         public override string Description()
32         {
33             return "混合咖啡";
34         }
35     }
View Code

Decorator(抽象裝飾類):Ingredients

 1 abstract class Ingredients:Coffee 
 2     {
 3         private Coffee coffee;
 4 
 5         public Ingredients(Coffee beverage)
 6         {
 7             this.coffee = beverage;
 8         }
 9         public override double Cost()
10         {
11             return coffee.Cost();
12         }
13         public override string Description()
14         {
15             return coffee.Description();
16         }  
17     }
View Code

ConcreteDecorator(具體裝飾類):Mocha、Whip、Milk

 1 class Mocha:Ingredients  
 2     {
 3         public Mocha(Coffee beverage):base(beverage )
 4         {
 5         }
 6   
 7         public override double Cost()
 8         {
 9             return base.Cost() + 10;
10         }
11 
12         public override string Description()
13         {
14             return base.Description()+",摩卡";
15         }
16     }
17 
18     class Whip : Ingredients //奶泡,由全脂牛奶攪拌而成,可拉絲
19     {
20         public Whip(Coffee beverage)
21             : base(beverage)
22         {   
23         }
24 
25         public override double Cost()
26         {
27             return base.Cost() + 8;
28         }
29 
30         public override string Description()
31         {
32             return base.Description()+",奶泡";
33         }
34     }
35 
36     class Milk : Ingredients //牛奶
37     {
38         public Milk(Coffee beverage)
39             : base(beverage)
40         {
41         }
42 
43         public override double Cost()
44         {
45             return base.Cost() + 6;
46         }
47 
48         public override string Description()
49         {
50             return base.Description() + ",牛奶";
51         }
52     }
View Code

Progream:

 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Coffee b = new Espresso();
 6 
 7             Coffee b1 = new Mocha(b);
 8 
 9             Coffee b2 = new Whip(b1);
10 
11             Coffee b3 = new Milk(b2);
12 
13             Console.WriteLine("名稱:{0}\n價格:{1}",b3.Description (),b3.Cost ());
14 
15             Console.Read();
16         }
17     }
View Code 

以上就是裝飾模式的介紹,裝飾模式的優點是它的擴展比使用繼承更靈活,不會使類很多很多。接下來是對關於Coffee的東西,感興趣的可以看下

 


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

-Advertisement-
Play Games
更多相關文章
  • 上一篇博客JavaScript動態載入script方式引用百度地圖API,Uncaught ReferenceError: BMap is not defined 這篇文章中我接觸到一個新的單詞:Promise,藉此來記錄一下它,引用來源:JS - Promise使用詳解--摘抄筆記 因為現在還不會 ...
  • 之前有收集了一些主流的隱藏鏈接代碼,最近又發現一種相當牛X的代碼,如下: 源代碼: <div style="position:absolute;left:expression(1-900);top:expression(3-999);">隱藏內容</a></div> 這個代碼中,expression ...
  • 一個網頁裡面的內容理解為一個XML或者說網頁本身也就是一個XML文檔,XML文檔都有很特殊的象徵:"標簽"也叫"節點"。 一個基本的網頁格式 這些是最基本的形態,但是其實它省略了最外面的一個標簽<document> 這其實才是它的本來面目(預設把document標簽給省略了)。document.bo ...
  • 學習專業知識,不是都靠自己頑強的意志,更多的是需要跟別人交流,重要的就是跟比你強的人交流,加一些氛圍比較好的交流學習群,或者別人的一句話就能讓你茅塞頓開,學技術切記不能閉門造車,學習的大忌。 5.遇到問題搞不清楚,只能百度,然後自己一團糟 遇到問題的時候,不假思索「百度」,但是很多時候我們是浪費了大 ...
  • 首先這邊我先貼一個地址:https://www.adobe.com/cn/products/photoshop.html 安裝軟體,這裡就不贅述了,真的不會,可以百度^_^我當初就是百度的,哈哈 說到PS,作為前端開發的同學,一點都不陌生 前端需要掌握的PS知識,也不是很多 針對頁面佈局,我們前端需 ...
  • 一、字體類屬性: 1.字體類型: font-family:字體1,字體2,字體3; 常用寫法: font-family:"微軟雅黑",Arial; 註:a) 多個字體之間用逗號分隔; b)中文字體要放在雙引號中,英文字體由多個單片語成時也要加雙引號; c) 瀏覽器優先識別字體1,如果找不到字體1,識 ...
  • 1. 通過axios實現數據請求 vue.js預設沒有提供ajax功能的。 所以使用vue的時候,一般都會使用axios的插件來實現ajax與後端伺服器的數據交互。 註意,axios本質上就是javascript的ajax封裝,所以會被同源策略限制。 下載地址: axios提供發送請求的常用方法有兩 ...
  • 開 成 都 建 材 發 票微信775130892開 成 都 建 材 發 票微信775130892開 成 都 建 材 發 票微信775130892開 成 都 建 材 發 票微信775130892 開 成 都 建 材 發 票微信775130892開 成 都 建 材 發 票微信775130892開 成 都 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...