Java設(shè)計(jì)模式——裝飾者模式

Java設(shè)計(jì)模式——裝飾者模式

我們來(lái)看一個(gè)圖片

10-55-59.jpg

圖片上面很清楚的顯示了我們裝飾者模式中的一些結(jié)構(gòu),那么我就來(lái)給大家分析一下:
1、Component是抽象構(gòu)建,什么意思呢,它是一個(gè)借口或者是抽象類,就是定義我們最核心的對(duì)象,也就是最原始的對(duì)象。

但是我們要注意

在裝飾模式中,必然有一個(gè)最基本、最核心、最原始的接口或抽象類充當(dāng)Component抽象構(gòu)件。
2、ConcreteComponent 具體構(gòu)件也就是說(shuō)ConcreteComponent是最核心、最原始、最基本的接口或抽象類的實(shí)現(xiàn),你要裝飾的就是它。
3、Decorator裝飾角色 一般是一個(gè)抽象類,做什么用呢?實(shí)現(xiàn)接口或者抽象方法,它里面可不一定有抽象的方法呀,在它的屬性里必然有一個(gè)private變量指向Component抽象構(gòu)件。
4、具體裝飾角色 什么意思呢,就是我們可以在這些類中具體的寫入方法。ConcreteDecoratorA和ConcreteDecoratorB是兩個(gè)具體的裝飾類,你要把你最核心的、最原始的、最基本的東西裝飾成其他東西。

定義差不多就講到這里了,那么接下來(lái)我們就開(kāi)始講例子

我們考試的時(shí)候我一般都是靠40多名的,而全班也只有40多名,那我們考試考完后,還要讓家長(zhǎng)簽字。這可愁壞我了,不過(guò)還好機(jī)智的我想出了個(gè)辦法,就是先說(shuō)我們的最高成績(jī),也沒(méi)比我高多少,然后在老爸看完成績(jī)單后,告訴他我在全班排第38名,這個(gè)也是實(shí)情,為啥呢?有將近十個(gè)同學(xué)退學(xué)了!這個(gè)情況我是不會(huì)說(shuō)的。不知道是不是當(dāng)時(shí)第一次發(fā)成績(jī)單時(shí)學(xué)校沒(méi)有考慮清楚,沒(méi)有寫上總共有多少同學(xué),排第幾名,反正是被我鉆了個(gè)空子。

我們來(lái)看看這個(gè)圖

13-15-53.jpg

圖上面寫了一個(gè)成績(jī)單的抽象類,我們可以按照前面一張圖的分析來(lái)看,

1、首先我們定義了一個(gè)抽象類SchoolReport.class

public abstract class SchoolReprt {

//成績(jī)單主要展示的就是你的成績(jī)情況
public abstract void report();
//成績(jī)單要家長(zhǎng)簽字,這是最要命的
public abstract void sign(String name);
}

2、然后我們定義了一個(gè)四年級(jí)的成績(jī)單FouthGradeSchoolReport 集成SchoolReport類,這個(gè)類是具體的實(shí)現(xiàn)類

public class FouthGradeSchoolReport extends SchoolReprt {

    //成績(jī)單
    @Override
    public void report() {
        // TODO Auto-generated method stub
        System.out.println("尊敬的XXX家長(zhǎng):");
        System.out.println("........");
        System.out.println("語(yǔ)文: 62   數(shù)學(xué):65   體育:98   自然:63");
        System.out.println("。。。。。。。。");
        System.out.println("家長(zhǎng)簽字:");
        
    }

    //家長(zhǎng)簽名
    public void sign(String name) {
        // TODO Auto-generated method stub
        System.out.println("家長(zhǎng)簽名:" +name );
    }

}

3、我們可以寫Decorator類來(lái)繼承SchoolReport 類,這些類就是用來(lái)修飾SchoolReport類的方法

public abstract class Decorator extends SchoolReprt {

    //首先我要知道是哪個(gè)成績(jī)單
    private SchoolReprt sr;
    //構(gòu)造函數(shù),傳遞成績(jī)單過(guò)來(lái)
    public Decorator(SchoolReprt sr){
        this.sr = sr;
    }
    //成績(jī)單還是要被看到的
    @Override
    public void report() {
        // TODO Auto-generated method stub
        this.sr.report();
    }

    //看完還是要簽名的
    @Override
    public void sign(String name) {
        // TODO Auto-generated method stub
        this.sr.sign(name);
    }

}

4、我們用多個(gè)類來(lái)修飾具體的角色

public class HighSCoreDecorator extends Decorator{

    //構(gòu)造函數(shù)
    public HighSCoreDecorator(SchoolReprt sr) {
        super(sr);
        // TODO Auto-generated constructor stub
    }
    
    //我要匯報(bào)最高成績(jī)
    private void reportHighScore(){
        System.out.println("這次考試語(yǔ)文最高是75,數(shù)學(xué)是78,自然是80");
        
    }
    //我要在老爸看成績(jī)單前告訴他最高成績(jī),否則等他一看,就掄起掃帚揍我,我哪里還有機(jī)會(huì)說(shuō)啊
    @Override
    public void report() {
        // TODO Auto-generated method stub
        this.reportHighScore();
        super.report();
    }
    
}
public class SortDecorator extends Decorator{

    
    //構(gòu)造函數(shù)
    public SortDecorator(SchoolReprt sr) {
        super(sr);
        // TODO Auto-generated constructor stub
    }

    //告訴老爸學(xué)校的排名情況
    private void reportSort(){
        System.out.println("我的排名是38名");
    }
    //老爸看完成績(jī)單后再告訴他,加強(qiáng)作用
    @Override
    public void report() {
        // TODO Auto-generated method stub
        super.report();
        this.reportSort();
    }


}

最后,我們開(kāi)始實(shí)現(xiàn)我們的Father ,也就是主方法

public class Father {

    public static void main(String[] args) {
        //把成績(jī)單拿過(guò)來(lái)
        SchoolReprt sr;
        //原裝的成績(jī)單
        sr = new FouthGradeSchoolReport();
        //加了最高分說(shuō)明的成績(jī)單
        sr = new HighSCoreDecorator(sr);
        //又加了成績(jī)排名的說(shuō)明
        sr = new SortDecorator(sr);
        //看成績(jī)單
        sr.report();
        //然后老爸一看,很開(kāi)心,就簽名了
        sr.sign("你爹"); 
    }
}

運(yùn)行結(jié)果就是:

這次考試語(yǔ)文最高是75,數(shù)學(xué)是78,自然是80
尊敬的XXX家長(zhǎng):
........
語(yǔ)文: 62   數(shù)學(xué):65   體育:98   自然:63
。。。。。。。。
家長(zhǎng)簽字:
我的排名是38名
家長(zhǎng)簽名:你爹

那我們來(lái)分析一下,這個(gè)裝飾類的用法

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

● 裝飾類和被裝飾類可以獨(dú)立發(fā)展,而不會(huì)相互耦合。換句話說(shuō),Component類無(wú)須知
道Decorator類,Decorator類是從外部來(lái)擴(kuò)展Component類的功能,而Decorator也不用知道具
體的構(gòu)件。
● 裝飾模式是繼承關(guān)系的一個(gè)替代方案。我們看裝飾類Decorator,不管裝飾多少層,返
回的對(duì)象還是Component,實(shí)現(xiàn)的還是is-a的關(guān)系。
● 裝飾模式可以動(dòng)態(tài)地?cái)U(kuò)展一個(gè)實(shí)現(xiàn)類的功能,這不需要多說(shuō),裝飾模式的定義就是如此。

缺點(diǎn):

對(duì)于裝飾模式記住一點(diǎn)就足夠了:多層的裝飾是比較復(fù)雜的。為什么會(huì)復(fù)雜呢?你想想看,就像剝洋蔥一樣,你剝到了最后才發(fā)現(xiàn)是最里層的裝飾出現(xiàn)了問(wèn)題,想象一下工作量吧,因此,盡量減少裝飾類的數(shù)量,以便降低系統(tǒng)的復(fù)雜度。

使用的場(chǎng)景

● 需要擴(kuò)展一個(gè)類的功能,或給一個(gè)類增加附加功能。
● 需要?jiǎng)討B(tài)地給一個(gè)對(duì)象增加功能,這些功能可以再動(dòng)態(tài)地撤銷。
● 需要為一批的兄弟類進(jìn)行改裝或加裝功能,當(dāng)然是首選裝飾模式。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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