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

裝飾者模式動(dòng)態(tài)地將責(zé)任附加到對(duì)象身上。若要拓展功能,裝飾者提供了比繼承更有彈性的替代方案。

用過(guò) QQ 的人都知道, 它有很多特權(quán)服務(wù),比如說(shuō) Vip , SVip 等。我們就以此為例對(duì)裝飾者模式進(jìn)行講解。

public class User {
    private String des;

    public User() {
        des = "I am common user";
    }

    public String getDes() {
        return des;
    }

    public void function() {
        System.out.println("I can use common function.");
    }
}

可見(jiàn),在這里我們只是一個(gè)普通用戶,而且也只能使用普通用戶的功能。那么接下來(lái),我們想要將普通用戶升級(jí)為會(huì)員,可以使用會(huì)員功能,怎么辦呢?難道這個(gè)時(shí)候我們還要去修改 function() 中的代碼嗎?如果真是這樣,工作量真是大的難以想象。而且出于讓我們得代碼遵守開(kāi)閉原則的目的,我們不能去盲目的修改源代碼。下面我們就用裝飾者模式將普通用戶升級(jí)為 Vip 用戶。

首先,我們需要保證裝飾者和被裝飾對(duì)象有相同的超類型,所以我們現(xiàn)在將用戶寫(xiě)成一個(gè)抽象類。

public abstract class User {

    public User() {
    }

    public String getDes() {
        return "I am common user";
    }

    public abstract void function();
}

下面開(kāi)始書(shū)寫(xiě)裝飾對(duì)象,裝飾者可以在被裝飾者行為之前或者之后或者覆蓋原功能加上自己的行為,以達(dá)到特定的目的。下面我們也為裝飾者對(duì)象寫(xiě)一個(gè)抽象類,并讓其繼承自 User 用以保證裝飾者和被裝飾者擁有共同的父類。

public abstract class Decorator extends User {
    public abstract String updateTime();
}

update() 方法用以記錄裝飾者添加到被裝飾者上的時(shí)間。下面我們就去寫(xiě)一個(gè) Vip 裝飾者,試一下功能。

public class VipDecorator extends Decorator {

    private Date mDate;
    private User user;

    public VipDecorator(User user) {
        mDate = new Date();
        this.user = user;
    }

    @Override
    public String updateTime() {
        return mDate.toString();
    }

    @Override
    public void function() {
        user.function();
        System.out.println("Vip function. ");
    }

    @Override
    public String getDes() {
        return "I am vip user.";
    }
}

其實(shí),我們應(yīng)該在Decorator 抽象類里將 getDes()function() 方法繼續(xù)聲明為抽象方法,強(qiáng)制子類實(shí)現(xiàn)這兩個(gè)方法,否則很可能會(huì)遺漏。比如我一開(kāi)始就漏寫(xiě)了 getDes() 方法。

public class Client {
    public static void main(String[] args) {

        User user = new CommonUser();
        System.out.println(user.getDes());
        user.function();

        System.out.println("-------------------------");

        user = new VipDecorator(user);
        System.out.println(user.getDes());
        user.function();
    }
}

輸出結(jié)果為

I am common user
Common function. 
-------------------------
I am vip user.
Common function. 
Vip function. 

可見(jiàn),這個(gè)時(shí)候我們想要的功能就實(shí)現(xiàn)了。而且,如果以后我們想增加其它的功能也不需要修改源代碼。比如說(shuō),現(xiàn)在我想添加 SVip.

public class SVipDecorator extends Decorator {
    private Date mDate;
    private User user;

    public SVipDecorator(User user) {
        mDate = new Date();
        this.user = user;
    }

    @Override
    public String updateTime() {
        return mDate.toString();
    }

    @Override
    public void function() {
        user.function();
        System.out.println("SVip function. ");
    }

    @Override
    public String getDes() {
        return "I am SVip user";
    }
}

在原來(lái)的基礎(chǔ)上進(jìn)項(xiàng)測(cè)試。

public class Client {
    public static void main(String[] args) {

        User user = new CommonUser();
        System.out.println(user.getDes());
        user.function();

        System.out.println("-------------------------");

        user = new VipDecorator(user);
        System.out.println(user.getDes());
        user.function();

        System.out.println("-------------------------");

        user = new SVipDecorator(user);
        System.out.println(user.getDes());
        user.function();
    }
}

打印結(jié)果為

I am common user
Common function. 
-------------------------
I am vip user.
Common function. 
Vip function. 
-------------------------
I am SVip user
Common function. 
Vip function. 
SVip function. 
最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 定義 裝飾者模式:在不改變?cè)愇募约安皇褂美^承的情況下,動(dòng)態(tài)地將責(zé)任附加到對(duì)象上,從而實(shí)現(xiàn)動(dòng)態(tài)拓展一個(gè)對(duì)象的功能...
    丶藍(lán)天白云夢(mèng)閱讀 2,036評(píng)論 2 23
  • 裝飾者模式:動(dòng)態(tài)地將責(zé)任附加到對(duì)象上。顧名思義,裝飾者模式的作用是對(duì)對(duì)象進(jìn)行包裝,最終得到一個(gè)自己想要的對(duì)象。簡(jiǎn)而...
    野比野比我是大雄閱讀 424評(píng)論 0 1
  • 2裝飾者模式 簡(jiǎn)單理解裝飾者模式 裝飾者模式就是在原來(lái)想做事情的接口上,在增加一些其他的想做的事情或者說(shuō)其他想裝飾...
    shuaidong閱讀 303評(píng)論 0 0
  • 概念 在不改變?cè)愇募约安皇褂美^承的情況下,動(dòng)態(tài)地將責(zé)任附加到對(duì)象上,從而實(shí)現(xiàn)動(dòng)態(tài)拓展的功能.它是通過(guò)創(chuàng)建一個(gè)包...
    Miss_差不多閱讀 333評(píng)論 0 0
  • 【禪語(yǔ)】 人生在世,如海上行船。隨時(shí)可能有風(fēng)浪出現(xiàn),沒(méi)有風(fēng)浪說(shuō)明這是一個(gè)沒(méi)有一點(diǎn)生機(jī)的死海。遇到風(fēng)浪,勇敢的人會(huì)努...
    武漢如心閱讀 495評(píng)論 0 4

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