1. 程式人生 > >(34)C#設計模式——裝飾者模式(Decorator Pattern)

(34)C#設計模式——裝飾者模式(Decorator Pattern)

引言

在軟體開發中,我們經常想要對一類物件新增不同的功能,例如要給手機新增貼膜、掛件、外殼等。如果此時使用繼承來實現的話,我們就需要定義無數的類,這樣會導致“子類爆炸”的問題。為了解決這個問題,可以使用裝飾者模式來動態地給一個物件新增額外的職責。

裝飾者模式的詳細介紹

定義

裝飾者模式以對客戶透明的方式動態地給一個物件附加上更多的職責,裝飾者模式相比生成子類可以更靈活地增加功能。

具體實現

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _23DecoratorPatternDemo
{
    /// <summary>
    /// 手機抽象類,即裝飾者模式中的抽象元件類
    /// </summary>
    public abstract class Phone
    {
        public abstract void Print();
    }
    /// <summary>
    /// 手機,即裝飾者模式中的具體元件類
    /// </summary>
    public class ApplePhone : Phone
    {
        public override void Print()
        {
            Console.WriteLine("開始執行具體的物件————蘋果手機");
        }
    }
    /// <summary>
    /// 裝飾抽象類,要讓裝飾完全取代抽象元件,必須繼承自Phone
    /// </summary>
    public abstract class Decorator :Phone
    {
        private Phone phone;
        public Decorator(Phone p)
        {
            this.phone = p;
        }
        public override void Print()
        {
            if(phone!=null)
            {
                phone.Print();
            }
        }
    }
    /// <summary>
    /// 貼膜,即具體裝飾者
    /// </summary>
    public class Sticker:Decorator
    {
        public Sticker(Phone p):base(p)
        {

        }
        public override void Print()
        {
            base.Print();
            //新增新行為
            AddSticker();
        }
        /// <summary>
        /// 新的行為方法
        /// </summary>
        public void AddSticker()
        {
            Console.WriteLine("現在蘋果手機有膜了");
        }
    }
    /// <summary>
    /// 手機掛件
    /// </summary>
    public class Accessories : Decorator
    {
        public Accessories(Phone p) : base(p)
        {
        }
        public override void Print()
        {
            base.Print();
            AddAccessories();
        }
        public void AddAccessories()
        {
            Console.WriteLine("現在蘋果手機有掛件了");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // 我買了個蘋果手機
            Phone phone = new ApplePhone();

            // 現在想貼膜了
            Decorator applePhoneWithSticker = new Sticker(phone);
            // 擴充套件貼膜行為
            applePhoneWithSticker.Print();
            Console.WriteLine("----------------------\n");

            // 現在我想有掛件了
            Decorator applePhoneWithAccessories = new Accessories(phone);
            // 擴充套件手機掛件行為
            applePhoneWithAccessories.Print();
            Console.WriteLine("----------------------\n");

            // 現在我同時有貼膜和手機掛件了
            Sticker sticker = new Sticker(phone);
            Accessories applePhoneWithAccessoriesAndSticker = new Accessories(sticker);
            applePhoneWithAccessoriesAndSticker.Print();
            Console.WriteLine();
        }
    }
}

從上面的Program類程式碼可以看出,客戶端可以動態地將手機配件加到手機上,如果需要新增另外的配件時,只需要新增一個繼承自Decorator類的對應類就行了。可以看出,裝飾者模式的擴充套件性是非常好的。

裝飾者模式中的角色

抽象構件角色(phone):給出一個抽象介面,以規範準備接受附加責任的物件

具體構件角色(ApplePhone):定義一個將要接受附加責任的類

裝飾角色(Decorator):持有一個構件物件的例項,並定義一個與抽象構件介面一致的介面

具體裝飾角色(Sticker和Accessories):負責給構件物件新增附加的責任

裝飾者模式的優缺點

優點:

  1. 裝飾者模式和繼承都是擴充套件物件的功能,但裝飾者模式比繼承更靈活
  2. 通過使用不同的具體裝飾類以及這些類的排列組合,設計師可以創造出很多不同行為的組合
  3. 裝飾者模式有很好的擴充套件性

缺點:

  • 裝飾者模式會導致設計中出現許多小物件,如果過度使用,會讓程式變的更復雜。並且更多的物件會是的差錯變得困難,特別是這些物件看上去都很像。

使用場景

  1. 需要擴充套件一個類的功能或給一個類增加附加責任。
  2. 需要動態地給一個物件增加功能,這些功能可以再動態地撤銷。
  3. 需要增加由一些基本功能的排列組合而產生的非常大量的功能

總結

裝飾者模式採用物件組合而非繼承的方式實現了在執行時動態地擴充套件物件的功能的能力,而且可以根據需要擴充套件多個功能,避免了單獨使用繼承帶來的“靈活性差”和“多子類衍生”問題。同時它很好地符合面向物件設計原則中“優先使用物件組合而非繼承”和“開放-封閉”原則。

相關推薦

34C#設計模式——裝飾模式Decorator Pattern

引言 在軟體開發中,我們經常想要對一類物件新增不同的功能,例如要給手機新增貼膜、掛件、外殼等。如果此時使用繼承來實現的話,我們就需要定義無數的類,這樣會導致“子類爆炸”的問題。為了解決這個問題,可以使用裝飾者模式來動態地給一個物件新增額外的職責。 裝飾者模式的詳細介紹

最常用的設計模式---裝飾模式C++實現

      上一篇說了介面卡模式,這一篇接著學習裝飾者模式。     想要擴充套件功能,裝飾者提供了有別於繼承的另外一種選擇。      裝飾者模式主要實現的功能是動態的給某一個類新增一些額外的功能,它是一個錦上添花者。想要擴充套件功能,裝飾者提供了有別於繼承的另外一種選

Java設計模式---裝飾模式用生活例子解釋通過裝飾類物件對方法進行實現介面的方法增強

裝飾者模式可以動態地給一個物件新增一些額外的職責。 就增加功能來說,Decorator模式相比生成子類更為靈活。 該模式的適用環境為: (1)在不影響其他物件的情況下,以動態、透明的方式給單個物件新增職責。 (2)處理那些可以撤消的職責。 (3)當不能採用生成子

javascript設計模式-裝飾模式9

裝飾者是一種為物件新增新特性的技術,它並不適用建立新子類的這種手段。裝飾者模式可以用來透明的把物件包裝在具有同樣介面的另一個物件之中。這樣我們就可以為物件新增一個方法或者一些行為,然後將方法呼叫傳

設計模式----裝飾模式decorator pattern

SchoolReport.java程式碼如下:package com.designPattern.decorator;public abstract class SchoolReport { public abstract void report(); public abst

設計模式-裝飾模式問題比較大,需要重新處理

設計原則:類應該對擴充套件開放,對修改關閉。在不修改現有程式碼的情況下,拓展,搭配新的行為。設計更加彈性應對改變,可以接受新的功能應對改變的需求。 遵循開放關閉原則會引入程式碼抽象層次,增加程式碼的複雜度。我們的注意力是在於設計中最有可能發生改變的地方,然後應用開放關閉原

設計模式--裝飾模式在IO體系中的應用

上一篇介紹了介面卡模式,它是將一個類的介面,轉化成客戶期望的另一個介面,介面卡讓原本介面不相容的類可以合作無間。裝飾者模式:動態的將責任附加到物件上(因為利用組合而不是繼承來實現,而組合是可以在執行時進行隨機組合的)用來擴充套件功能。若要擴充套件功能,裝飾者提供

C# - 設計模式 - 裝飾模式

private 實現類 comm 回路 匯總 abs round C# 由於 裝飾者模式 問題場景 如果要計算一杯咖啡的價格,只需要調用其獲取價格的方法就可以了,但是如果需要加一些材料,比如牛奶、巧克力、糖等等,這些材料也必須返回它們價格以便於用於匯總計算,但是材料有很

C#設計模式——裝飾模式

方式 實例 oid spa als note 客戶 基本功 pan 一、裝飾者模式介紹: 裝飾者模式——以對客戶透明的方式動態地給一個對象添加額外的職責,采用對象組合而非繼承的方式實現了再運行時動態地擴展對象功能的能力,相比生成子類可以更靈活地增加功能,而且可以根據需要擴展

C++設計模式--裝飾模式

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

C#設計模式-裝飾模式

using System; using System.Collections.Generic; namespace TestCS { class Program { static void Main(string[] args) {

C#設計模式-裝飾模式

一.裝飾者模式的定義: 裝飾模式是在不必改變原類檔案和使用繼承的情況下,動態地擴充套件一個物件的功能。它是通過建立一個包裝物件,也就是裝飾來包裹真實的物件。 結構: (1)抽象構件(Component)角色:給出一個抽象介面,以規範準備接收附加責任的物件。 (2)具體構件

Java設計模式裝飾模式

解決 over 裝飾者模式 pack img 應該 ora 我們 lan 目錄      一、問題引入  二、設計原則  三、用裝飾者模式解決問題  四、裝飾者模式的特點  五、裝飾者模式的定義  六、裝飾者模式的實現  七、java.io包內的裝飾者模式

javascript設計模式——裝飾模式

應用 提交表單 不同 ora fin input 是否為空 插件 和數 前面的話   在程序開發中,許多時候都並不希望某個類天生就非常龐大,一次性包含許多職責。那麽可以使用裝飾者模式。裝飾者模式可以動態地給某個對象添加一些額外的職責,而不會影響從這個類中派生的其他對象。本

設計模式——裝飾模式

什麽 很多 方法 info 改變 劃分 llb 設計 nts - 什麽是裝飾者模型 裝飾者模型通過組合的方式擴展對象的特性,動態地給對象添加額外的職責。在增加功能上,裝飾模式比生成子類更加靈活。 - 職責劃分 Component抽象構建,是接口或者抽象類,就是定義原始對象

設計模式-裝飾模式(Go語言描述)

什麼是裝飾者模式 好久沒有更新設計模式系列的部落格了, 今天我們來聊一聊裝飾者模式, 用過java的同學肯定對裝飾者模式非常熟悉,就算你不知道什麼是裝飾者模式這概念, 你也一定在程式碼中經常用到這個模式,為什麼這麼說呢? 大家都用過java中的流吧, 我們可以這樣寫: new B

android設計模式——裝飾模式

定義:允許向一個現有的物件新增新的功能,同時又不改變其結構。 使用場景:能夠動態地擴充套件類的功能 應用舉例:一個畫可以被裝在畫框裡,並且被蒙上玻璃,這時候畫,玻璃,畫框組成了一個東西。 類圖: Comppoent: 抽象元件 ConcreteComponet:元件的具體

java設計模式--裝飾模式

照例搬一篇文章連線,我一般會選擇帶有uml圖的 方便理解,我只貼程式碼,因為我覺得別人理解的比我透徹,寫的比我好 http://www.cnblogs.com/stonefeng/p/5679638.html 裝飾者模式可以給物件新增一些額外的東西,設計模式那種書中舉例是星巴克的例子,如果每一種做

設計模式-裝飾模式(Decorator)

概述 定義 : 在不改變原有物件的基礎之上, 將功能附加到物件上 提供了比繼承更有彈性的替代方案(擴充套件原有物件功能) 又叫包裝器Wrapper, 介面卡模式也被稱之為包裝器 型別 : 結構型 適用場景 擴充套件一個類的功能或給一個類

Java設計模式-裝飾模式

定義: 裝飾者是在不改變物件的情況下動態給物件新增屬性和行為,將責任動態的附加在物件上。 與繼承有類似功能即擴充套件功能。 裝飾者模式與繼承的區別: **繼承:**在子類擴充套件功能的時候是靜態的,並且是已知需要擴充套件的功能,是在編譯時實現的。 **裝飾者模式:**比繼承更