(21)裝飾模式

定義

動(dòng)態(tài)地給一個(gè)對象添加一些額外的職責(zé),就增加功能來說,裝飾模式相比生成子類更為靈活。其實(shí)通俗的說就說給一個(gè)類增加新的功能(解決java不能擴(kuò)展類方法的問題,kotlin改進(jìn)了java這個(gè)不能擴(kuò)展的問題)


使用場景

  • 需要透明且動(dòng)態(tài)的擴(kuò)展類的功能時(shí)

其實(shí)就是擴(kuò)展父類

UML圖

裝飾模式.png
角色介紹

簡單的例子

人事要穿衣服的,將人定義為一個(gè)抽象類,將穿衣的行為定義為一個(gè)抽象方法

/** 人的抽象類,相當(dāng)于Component類
 * 
 */
public abstract class Person {
    /**
     *
     *  Person下有個(gè)穿著的抽象方法,
     * */
    public abstract void dressed();
}

Boy類繼承于Person類,該類僅對Person中的dresses方法做了具體的實(shí)現(xiàn),而Boy類就是我們所要裝飾的具體對象

/** Boy類,相當(dāng)于具體實(shí)現(xiàn)類ConcreteComponent類
 * 
 */
public class Boy extends Person {

    @Override
    public void dressed() {
        System.out.println("原始穿著:內(nèi)衣內(nèi)褲");
    }
}

裝飾者

**
 * 抽象的裝飾類,類似Decorator類
 * 
 */
public abstract class PersonCloth extends Person {

    protected Person mPerson;//保持一個(gè)Person類的引用

    public PersonCloth(Person mPerson) {
        this.mPerson = mPerson;
    }

    @Override
    public void dressed() {
        //調(diào)用Person類中的dressed方法
        mPerson.dressed();
    }
}

具體的裝飾類,其實(shí)就是為了Boy類提供擴(kuò)展

/** 昂貴的 本質(zhì)上僅僅是將原有方法和新邏輯進(jìn)行封裝整合了
 * 具體的裝飾類,類似ConcreteDecoratorA
 *
 */
public class ExpensiveCloth extends PersonCloth {

    public ExpensiveCloth(Person mPerson) {
        super(mPerson);
    }

    private void dressShirt() {
        System.out.println("裝飾:穿上了短袖");
    }

    private void dressLeather() {
        System.out.println("裝飾:穿上了皮衣");
    }

    private void dressJean() {
        System.out.println("裝飾:穿上了牛仔褲");
    }

    @Override
    public void dressed() {
        super.dressed();//這里就是Boy類的原始方法,只穿內(nèi)褲內(nèi)衣
        dressShirt();
        dressLeather();
        dressJean();
    }
}
/** 便宜的
 * 具體的裝飾類,類似ConcreteDecoratorA
 * 
 */
public class CheapCloth extends PersonCloth {

    public CheapCloth(Person mPerson) {
        super(mPerson);
    }

    private void dressShorts() {
        System.out.println("裝飾:穿上了短褲");
    }


    @Override
    public void dressed() {
        super.dressed();
        dressShorts();
    }
}
** 測試類
 * 
 */
public class Test {
    public static void main(String[] args){
        //首先要有一個(gè)Person男孩
        Person person = new Boy();
        //然后為他穿上便宜的衣服
        PersonCloth cheapCloth = new CheapCloth(person);
        cheapCloth.dressed();

        System.out.println();
        System.out.println();
        System.out.println();
        //或者穿上貴的衣服
        PersonCloth expensiveCloth = new ExpensiveCloth(person);
        expensiveCloth.dressed();
    }
}


結(jié)果:

原始穿著:內(nèi)衣內(nèi)褲
裝飾:穿上了短褲



原始穿著:內(nèi)衣內(nèi)褲
裝飾:穿上了短袖
裝飾:穿上了皮衣
裝飾:穿上了牛仔褲

例子UML類圖


優(yōu)點(diǎn)

  • 擴(kuò)展類方法

缺點(diǎn)

  • 和代理模式易混淆
    裝飾模式:以對客戶端透明的方式擴(kuò)展對象的功能,是繼承關(guān)系的一個(gè)替代方案(為裝飾的對象增強(qiáng)功能)
    代理模式:給對象提供一個(gè)代理對象,并用代理對象來控制對原有對象的引用(對代理的對象施加控制,但不對對象本身的功能進(jìn)行增強(qiáng))

源代碼:DesignPattern



參考

《Android源碼設(shè)計(jì)模式解析與實(shí)戰(zhàn)讀書》
各大佬博客


end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式基本原則 開放-封閉原則(OCP),是說軟件實(shí)體(類、模塊、函數(shù)等等)應(yīng)該可以拓展,但是不可修改。開-閉原...
    西山薄涼閱讀 4,086評論 3 14
  • 本文首發(fā)于個(gè)人博客:Lam's Blog - 談?wù)?3種設(shè)計(jì)模式在Android源碼及項(xiàng)目中的應(yīng)用,文章由Mark...
    格子林ll閱讀 4,776評論 1 105
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,715評論 19 139
  • 設(shè)計(jì)模式匯總 一、基礎(chǔ)知識 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 4,098評論 1 15
  • 1 - 閱讀感悟 (1)跟林語堂學(xué)寫作。 ①中文寫作喜歡用成語,或者是把長句拆成很多短句,讀起來很有節(jié)奏感。林語堂...
    ElaineLKN閱讀 411評論 0 0

友情鏈接更多精彩內(nèi)容