1. 程式人生 > >設計模式(結構型)之裝飾者模式(Decorator Pattern)

設計模式(結構型)之裝飾者模式(Decorator Pattern)

PS一句:最終還是選擇CSDN來整理髮表這幾年的知識點,該文章平行遷移到CSDN。因為CSDN也支援MarkDown語法了,牛逼啊!

概述

裝飾模式可以在不改變一個物件本身功能的基礎上給物件增加額外的新行為。裝飾模式是一種用於替代繼承的技術,它通過一種無須定義子類的方式來給物件動態增加職責,使用物件之間的關聯關係取代類之間的繼承關係。在裝飾模式中引入了裝飾類,在裝飾類中既可以呼叫待裝飾的原有類的方法,還可以增加新的方法,以擴充原有類的功能。

這裡寫圖片描述

核心

概念: 動態地給一個物件增加一些額外的職責,就增加物件功能來說,裝飾模式比生成子類實現更為靈活。裝飾模式是一種物件結構型模式。

重點:

裝飾者模式結構重要核心模組:

Component(抽象構件)

它是具體構件和抽象裝飾類的共同父類,聲明瞭在具體構件中實現的業務方法,它的引入可以使客戶端以一致的方式處理未被裝飾的物件以及裝飾之後的物件,實現客戶端的透明操作。

ConcreteComponent(具體構件)

它是抽象構件類的子類,用於定義具體的構件物件,實現了在抽象構件中宣告的方法,裝飾器可以給它增加額外的職責(方法)。

Decorator(抽象裝飾類)

它也是抽象構件類的子類,用於給具體構件增加職責,但是具體職責在其子類中實現。它維護一個指向抽象構件物件的引用,通過該引用可以呼叫裝飾之前構件物件的方法,並通過其子類擴充套件該方法,以達到裝飾的目的。

ConcreteDecorator(具體裝飾類)

它是抽象裝飾類的子類,負責向構件新增新的職責。每一個具體裝飾類都定義了一些新的行為,它可以呼叫在抽象裝飾類中定義的方法,並可以增加新的方法用以擴充物件的行為。

注意事項:裝飾者模式使用時需要注意以下幾個問題:

  • 儘量保持裝飾類的介面與被裝飾類的介面相同,這樣,對於客戶端而言,無論是裝飾之前的物件還是裝飾之後的物件都可以一致對待。這也就是說,在可能的情況下,我們應該儘量使用透明裝飾模式。

  • 儘量保持具體裝飾類是一個“輕”類,也就是說不要把太多的行為放在具體構件類中,我們可以通過裝飾類對其進行擴充套件。

  • 如果只有一個具體構件類,那麼抽象裝飾類可以作為該具體構件類的直接子類。

使用場景

在不影響其他物件的情況下,以動態、透明的方式給單個物件新增職責。

當不能採用繼承的方式對系統進行擴充套件或者採用繼承不利於系統擴充套件和維護時可以使用裝飾模式。

不能採用繼承的情況主要有系統中存在大量獨立的擴充套件,為支援每一種擴充套件或者擴充套件之間的組合將產生大量的子類,使得子類數目呈爆炸性增長;類已定義為不能被繼承(譬如final類)。

程式猿例項

這裡還是以苦逼的程式猿為例來說明裝飾者模式。假設有兩個程式設計師他們原來只會各自的技能,現在需要讓Android程式猿具備設計模式技能,那就給他裝飾一下。如下實現:

package yanbober.github.io;

//Component(抽象構件)
interface ProgramMonkey {
    void skills();
}
//ConcreteComponent(具體構件)
class AndroidProgramMonkey implements ProgramMonkey {
    @Override
    public void skills() {
        System.out.println("會寫Android程式碼!");
    }
}
//ConcreteComponent(具體構件)
class PHPProgramMonkey implements ProgramMonkey {
    @Override
    public void skills() {
        System.out.println("會寫PHP程式碼!");
    }
}
//Decorator(抽象裝飾類)
class ProgramMonkeyDecorator implements ProgramMonkey {
    protected ProgramMonkey mProgramMonkey;

    public ProgramMonkeyDecorator(ProgramMonkey mProgramMonkey) {
        this.mProgramMonkey = mProgramMonkey;
    }

    public void skills() {
        mProgramMonkey.skills();
    }
}
//ConcreteDecorator(具體裝飾類)
class PatternDecorator extends ProgramMonkeyDecorator {
    public PatternDecorator(ProgramMonkey mProgramMonkey) {
        super(mProgramMonkey);
    }

    @Override
    public void skills() {
        super.skills();
        System.out.println("會設計模式!");
    }
}

public class Main {
    public static void main(String[] args) {
        //有一個Android程式猿只會寫Android程式碼
        ProgramMonkey programMonkey = new AndroidProgramMonkey();
        programMonkey.skills();
        //裝飾一下他,裝逼的技能,他竟然除了寫Android還懂設計模式
        programMonkey = new PatternDecorator(programMonkey);
        programMonkey.skills();

        programMonkey = new PHPProgramMonkey();
        programMonkey.skills();
    }
}

總結一把

裝飾模式優點如下:

  • 對於擴充套件一個物件的功能,裝飾模式比繼承更加靈活性,不會導致類的個數急劇增加。
  • 可以通過一種動態的方式在執行時選擇不同的具體裝飾類,從而實現不同的行為。
  • 可以對一個物件進行多次裝飾,通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創造出很多不同行為的組合,得到功能更為強大的物件。
  • 具體構件類與具體裝飾類可以獨立變化,使用者可以根據需要增加新的具體構件類和具體裝飾類,原有類庫程式碼無須改變,符合“開閉原則”。

裝飾模式缺點如下:

  • 使用裝飾模式進行系統設計時將產生很多小物件,這些物件的區別在於它們之間相互連線的方式有所不同,而不是它們的類或者屬性值有所不同,大量小物件的產生勢必會佔用更多的系統資源,在一定程式上影響程式的效能。
  • 裝飾模式提供了一種比繼承更加靈活機動的解決方案,但同時也意味著比繼承更加易於出錯,排錯也很困難,對於多次裝飾的物件,除錯時尋找錯誤可能需要逐級排查,較為繁瑣。

相關推薦

設計模式(結構)裝飾模式(Decorator Pattern)

PS一句:最終還是選擇CSDN來整理髮表這幾年的知識點,該文章平行遷移到CSDN。因為CSDN也支援MarkDown語法了,牛逼啊! 概述 裝飾模式可以在不改變一個物件本身功能的基礎上給物件增加額外的新行為。裝飾模式是一種用於替代繼承的技術,它通過一

結構裝飾模式及相關應用

文章目錄 裝飾者(Decorator) 優缺點 應用場景 Java I/O中的應用 Spring中的應用 MyBatis中的應用 參考資料 裝飾者(Decorator) 在不

7、設計模式(結構)橋接模式

作用 將抽象部分與實現部分分離,使它們都可以獨立的變化 何時使用 實現系統可能有多個角度分類,每一種角度都可能變化 優點 抽象和實現的分離 優秀的擴充套件能力 實現細節對客戶透明 例項 下面

設計模式(結構)享元模式(Flyweight Pattern)

PS一句:最終還是選擇CSDN來整理髮表這幾年的知識點,該文章平行遷移到CSDN。因為CSDN也支援MarkDown語法了,牛逼啊! 概述 當一個軟體系統在執行時產生的物件數量太多,將導致執行代價過高,帶來系統性能下降等問題。所以需要採用一個共享來避

"圍觀"設計模式(13)--結構裝飾模式Decorator Pattern

修飾模式,是面向物件程式設計領域中,一種動態地往一個類中新增新的行為的設計模式。就功能而言,修飾模式相比生成子類更為靈活,這樣可以給某個物件而不是整個類新增一些功能。----WIKIPEDIA 個人

設計模式裝飾模式

一點 ron 測試類 實現類 stub generated class void nbsp 一.裝飾者模式特點:1.裝飾者和被裝飾者對象有相同的超類2.可以用一個或多個裝飾者包裝一個對象3.由於裝飾者和被裝飾者具有相同超類,所以任何需要被包裝對象的場合,可以用裝飾過的對象代

《Head First 設計模式裝飾模式

的人 開放 override ext es2017 必須 想要 ret ted 前言:   時間過得挺快的,轉眼間就到了十月中旬了,再晃著晃著新的一年就要來臨。今天lz有幸來到了浙大圖書館來學習,想想自己已經畢業兩年了,今日再次踏進校園裏,心裏頗有一絲感悟,說不出來,只有把

23種設計模式學習裝飾模式

eth light 裝飾者模式 per int ring ava 功能 接口 裝飾著模式是動態的增強類的功能,要求被裝飾的類必選實現了某個接口 被裝飾類接口 public interface Source { void method1(); } 被裝飾類

JDK設計模式——裝飾模式(適配器模式)

div rgs static eight 裝飾者 參數 decorator 裝飾器 方式 假定已經有三個類A,B和C他們的繼承關系如下                      ClassA Class B extends A Class C

java的23種設計模式裝飾模式

這裡給大家推薦一篇文章裡面介紹了23種設計模式https://www.aliyun.com/jiaocheng/811770.html; 下面則是我學習裝飾者的見解: 關於裝飾者模式運用的地方其實有很多,我第一次接觸到就是io流中,比如像這樣的: new InputStreamRea

設計模式 - 裝飾模式

一、什麼是裝飾者模式 裝飾著模式:簡單的一句話理解就是,動態的給一個物件新增一些額外的功能,裝飾者模式相對於生成子類更加的靈活。 我們來看下裝飾者模式的UML圖: 二、裝飾者模式的構成 Component(抽象構件):它是裝飾類和具體構件的公共父類;

Java 設計模式裝飾模式

本文為筆者學習《Head First設計模式》的筆記,並加入筆者自己的理解和歸納總結 裝飾者模式動態地將責任附加到物件上。若要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。 結構圖 雞尾酒Cocktail一般以伏特加(Vodka)、威士忌(Whisky)等烈酒或是葡萄

10、設計模式(結構)外觀模式

作用 為子系統中的一組介面提供一個一致的介面,外觀模式定義了一個高層介面,這個介面使得這一子系統更加容易使用 何時使用 客戶端不需要知道系統內部的複雜聯絡,整個系統只需提供一個"接待員"即可。 

22、設計模式裝飾模式

抽象商品類 /** * 商品 */ public abstract class AbstractGoods { public abstract String getName() ; public abstract Double getPrice();

ES6設計模式裝飾模式

就是不修改原來的物件的情況下,對物件的功能進行擴充的一種方法。遵循的是開放封閉原則,類可以擴充但是不可以修改。 各種粥裡面有不同的調料,不同的調料可以加不同的量,最後粥的價錢不等。下面是es實現: // 注意粥裡面可以加入不同的調料,調料不一樣價錢不一樣。 class Porridge{ constru

設計模式裝飾模式大概思想

什麼是裝飾者模式呢,為什麼要用裝飾者模式,用了會有什麼好處呢? 那麼下來我給大家介紹一下什麼是裝飾者模式: 裝飾者模式見名知意就是給前面寫的東西裝飾一下,讓它變成對我們最有用的一方面,在面向介面程式設計中有很廣泛的應用。 官方的話是這樣講的:裝飾模式指的是在不必改變原類檔案和使用繼承的情

Android設計模式裝飾模式(Decorator Pattern)

概論 在Android原始碼裡很多時候會看到這個模式。下面來講一些這個模式。 裝飾者模式主要的優點是動態給一個物件新增一些額外的職責。使用Decorator模式相比用生成子類方式達到功能的擴充顯得更為靈活。缺點是,要建立比繼承更多的物件。 先來個熱身,

Java設計模式裝飾模式

一、概念       裝飾者模式:動態的將責任附加到物件上,若要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。        關係圖: 說明: 裝飾者和被裝飾者物件有相同的超類你可以擁有一個

JAVA設計模式初探裝飾模式

這個模式花費了挺長時間,開始有點難理解,其實就是 定義:動態給一個物件新增一些額外的職責,就象在牆上刷油漆.使用Decorator模式相比用生成子類方式達到功能的擴充顯得更為靈活。設計初衷:通常可以使用繼承來實現功能的拓展,如果這些需要拓展的功能的種類很繁多,那麼勢必生成很

設計模式裝飾Decorator模式

首先來看一個場景,如圖: 工人分為很多種類,比如電工,管道工等等,同時又有A公司的電工,B公司的電工,A公司的管道工,B公司的管道工等等,那麼當有M個工種和N個公司的時候,就會有 M * N 個子類,這個繼承體系就會變得很龐大和複雜。那麼如何簡化呢,那麼