3. 裝飾者模式

設(shè)計(jì)原則

  • 對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉
定義和實(shí)現(xiàn)思路
動(dòng)態(tài)地將責(zé)任附加到對(duì)象上。若要擴(kuò)展功能,裝飾者提供了比繼承更有彈性的替代方案。
  • 使用組合的方式加入新行為。
  • 裝飾者和被裝飾者必須為同一類型,因?yàn)檠b飾者必須能夠取代被裝飾者。
  • 被裝飾者通過構(gòu)造器傳入裝飾者中
  • 維持開放-閉合原則。對(duì)擴(kuò)展開放、對(duì)修改封閉

UML模型

裝飾者模式.jpg

具體代碼實(shí)現(xiàn)

/**
 * 裝飾者、被裝飾者共同的基類
 *
 * @author luhuancheng
 * @since 2018/3/27 22:34
 */
public abstract class Beverage {

    String description = "Unknown Beverage";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}
/**
 * 裝飾者基類
 *
 * @author luhuancheng
 * @since 2018/3/27 22:36
 */
public abstract class CondimentDecorator extends Beverage {

    public abstract String getDescription();

}
/**
 * 具體的一個(gè)裝飾者
 *
 * @author luhuancheng
 * @since 2018/3/27 22:47
 */
public class Mocha extends CondimentDecorator {

    /**
     * 持有被裝飾者實(shí)例
     */
    Beverage beverage;

    /**
     * 利用裝飾者的構(gòu)造器把被裝飾者傳入,裝飾者、被裝飾者擁有簽名一致的方法。
     * 對(duì)其調(diào)用時(shí),可以在裝飾者增加我們需要的邏輯。即所謂擴(kuò)展功能
     *
     * @param beverage
     */
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }

    /**
     * 調(diào)用與被裝飾者簽名一致的方法,可以在被裝飾者的基礎(chǔ)上,進(jìn)行功能擴(kuò)展
     *
     * @return
     */
    @Override
    public double cost() {
        return .20 + beverage.cost();
    }
}
/**
 * 另一個(gè)裝飾者
 *
 * @author luhuancheng
 * @since 2018/3/27 22:51
 */
public class Soy extends CondimentDecorator {

    Beverage beverage;

    public Soy(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Soy";
    }

    @Override
    public double cost() {
        return .15 + beverage.cost();
    }
}
/**
 * 通過裝飾者的基類CondimentDecorator,不斷的擴(kuò)充裝飾者
 *
 * @author luhuancheng
 * @since 2018/3/27 22:51
 */
public class Whip extends CondimentDecorator {

    Beverage beverage;

    public Whip(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Whip";
    }

    @Override
    public double cost() {
        return .15 + beverage.cost();
    }
}

/**
 * 被裝飾者
 *
 * @author luhuancheng
 * @since 2018/3/27 22:43
 */
public class DarkRoast extends Beverage {

    public DarkRoast() {
        description = "DarkRoast Coffee";
    }

    @Override
    public double cost() {
        return .99;
    }
}
/** 客戶端使用
 * @author luhuancheng
 * @since 2018/3/27 22:53
 */
public class Client {

    public static void main(String[] args) {
        // 創(chuàng)建一個(gè)被裝飾者
        Beverage beverage2 = new DarkRoast();
        // 使用裝飾者(Mocha)裝飾被裝飾者(beverage2)
        beverage2 = new Mocha(beverage2);
        // 使用裝飾者(Mocha)裝飾被裝飾者(beverage2)
        beverage2 = new Mocha(beverage2);
        // 使用裝飾者(Mocha)裝飾被裝飾者(beverage2)
        beverage2 = new Whip(beverage2);
        System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
    }

}
運(yùn)行Client#main將輸出
# 通過裝飾者M(jìn)ocha、Whip,擴(kuò)展了被裝飾者的功能(即getDescription()方法)
DarkRoast Coffee, Mocha, Mocha, Whip $1.5399999999999998

調(diào)用時(shí)序圖

裝飾者時(shí)序圖.jpg

總結(jié)

  • 裝飾者有點(diǎn)類似于靜態(tài)代理,把對(duì)自身方法的調(diào)用委托給其他類來執(zhí)行,在其他類中進(jìn)行功能擴(kuò)展
?著作權(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)容