02.裝飾者模式

02.裝飾者模式

1镜悉、認(rèn)識裝飾者模式

購買咖啡時(shí)祟辟,除了咖啡的各種口味以外,還可以加入各種調(diào)料侣肄,例如:蒸奶旧困、豆?jié){、摩卡或奶蓋稼锅,星巴克會(huì)根據(jù)加入不同的調(diào)料收取不同的費(fèi)用吼具,當(dāng)然還有大中小杯等等。

如果我們使用類繼承的方式缰贝,會(huì)導(dǎo)致類數(shù)目爆炸馍悟、設(shè)計(jì)死板,以及基類加入的新功能并不適用于所有的子類剩晴。

所以我們要采取不一樣的做法锣咒,我們以飲料為主體,然后采用調(diào)料類赞弥、體積類來修飾毅整。

(1)拿一個(gè)深焙咖啡(DarkRoast)對象

(2)以摩卡(Mocha)對象來修飾

(3)以奶泡(Whip)來修飾

(4)以中杯(Medium)來修飾

(5)調(diào)用cost()方法,并依賴委托(delegate)將調(diào)料的價(jià)錢加上

2绽左、定義

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

BD65E96F-442F-4A17-8CAD-429B18D95F1D_1_105_c.jpeg

3戏蔑、設(shè)計(jì)原則:

開放-關(guān)閉原則

類應(yīng)該對擴(kuò)展開放,對修改關(guān)閉鲁纠。

我們的目標(biāo)是允許類容易拓展总棵,在不修改現(xiàn)有代碼的情況下,就可搭配新的行為改含。

4情龄、設(shè)計(jì)

5DC568F8-7135-4D6B-B40D-D48673A49C73_1_201_a.jpeg

代碼實(shí)現(xiàn):

(1)裝飾者總抽象類

public abstract class Beverage {
    public String description = "Unknown Beverage";

    public String getDescription(){
        return description;
    }
    public abstract double cost();
}

(2)調(diào)料裝飾者 抽象類

public abstract class CondimentDecorator extends Beverage {
    @Override
    public abstract String getDescription();
}

(3)容量裝飾者 抽象類

public abstract class Capacity extends Beverage {
    @Override
    public abstract String getDescription();
}

(4)四種咖啡實(shí)現(xiàn)類

/**
 * 深度烘焙咖啡類
 */
public class DarkRoast extends Beverage {

    public DarkRoast(){
        this.description = "DarkRoast";
    }

    @Override
    public double cost() {
        return 2.99;
    }
}
/**
 * 貓屎咖啡
 */

public class Decat extends Beverage {

    public Decat(){
        this.description = "Decat";
    }

    @Override
    public double cost() {
        return 1.89;
    }
}
/**
 * 濃縮咖啡類
 */
public class Espresso extends Beverage {

    public Espresso(){
        this.description = "Espresso";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}
/**
 * 首選咖啡(星巴克咖啡名)
 */
public class HouseBlend extends Beverage {
    public HouseBlend() {
        description = "HouseBlend";
    }

    @Override
    public double cost() {
        return 0.89;
    }
}

(5)調(diào)料類

/**
 * 摩卡  調(diào)料類
 */
public class Mocha extends CondimentDecorator {
    private Beverage beverage;

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

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

    @Override
    public double cost() {
        return .20 + beverage.cost();
    }
}
/**
 * 大豆  調(diào)料類
 */
public class Soy extends CondimentDecorator {
    private Beverage beverage;

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

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

    @Override
    public double cost() {
        return .30 + beverage.cost();
    }
}
/**
 * 鮮奶  調(diào)料類
 */
public class Whip extends CondimentDecorator {
    private Beverage beverage;

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

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

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

(6)容量類

/**
 * 大杯
 */
public class Big extends Capacity {
    private Beverage beverage;

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

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

    @Override
    public String getDescription() {
        return beverage.getDescription() + " ,Big";
    }
}
/**
 * 中杯
 */

public class Medium extends Capacity {
    private Beverage beverage;

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

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

    @Override
    public String getDescription() {
        return this.beverage.getDescription() + " ,Medium";
    }
}
/**
 * 小杯
 */

public class Small extends Capacity {
    private Beverage beverage;

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

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

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

(7)測試類

public class StarbuzzCoffee {
    public static void main(String[] args) {
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());

        Beverage beverage1 = new DarkRoast();
        beverage1 = new Mocha(beverage1);
        beverage1 = new Mocha(beverage1);
        beverage1 = new Whip(beverage1);
        System.out.println(beverage1.getDescription() + " $" + beverage1.cost());

        Beverage beverage2 = new HouseBlend();
        beverage2 = new Soy(beverage2);
        beverage2 = new Mocha(beverage2);
        beverage2 = new Whip(beverage2);
        beverage2 = new Big(beverage2);
        System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
    }
}

結(jié)果:

Espresso $1.99
DarkRoast,Mocha,Mocha,Whip $3.8900000000000006
HouseBlend,Soy,Mocha,Whip ,Big $2.09

1、認(rèn)識裝飾者模式

購買咖啡時(shí)捍壤,除了咖啡的各種口味以外骤视,還可以加入各種調(diào)料,例如:蒸奶鹃觉、豆?jié){专酗、摩卡或奶蓋,星巴克會(huì)根據(jù)加入不同的調(diào)料收取不同的費(fèi)用帜慢,當(dāng)然還有大中小杯等等笼裳。

如果我們使用類繼承的方式唯卖,會(huì)導(dǎo)致類數(shù)目爆炸粱玲、設(shè)計(jì)死板躬柬,以及基類加入的新功能并不適用于所有的子類。

所以我們要采取不一樣的做法抽减,我們以飲料為主體允青,然后采用調(diào)料類、體積類來修飾卵沉。

(1)拿一個(gè)深焙咖啡(DarkRoast)對象

(2)以摩卡(Mocha)對象來修飾

(3)以奶泡(Whip)來修飾

(4)以中杯(Medium)來修飾

(5)調(diào)用cost()方法颠锉,并依賴委托(delegate)將調(diào)料的價(jià)錢加上

2、定義

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

BD65E96F-442F-4A17-8CAD-429B18D95F1D_1_105_c.jpeg

3停撞、設(shè)計(jì)原則:

開放-關(guān)閉原則

類應(yīng)該對擴(kuò)展開放瓷蛙,對修改關(guān)閉。

我們的目標(biāo)是允許類容易拓展戈毒,在不修改現(xiàn)有代碼的情況下艰猬,就可搭配新的行為。

4埋市、設(shè)計(jì)

5DC568F8-7135-4D6B-B40D-D48673A49C73_1_201_a.jpeg

代碼實(shí)現(xiàn):

(1)裝飾者總抽象類

public abstract class Beverage {
    public String description = "Unknown Beverage";

    public String getDescription(){
        return description;
    }
    public abstract double cost();
}

(2)調(diào)料裝飾者 抽象類

public abstract class CondimentDecorator extends Beverage {
    @Override
    public abstract String getDescription();
}

(3)容量裝飾者 抽象類

public abstract class Capacity extends Beverage {
    @Override
    public abstract String getDescription();
}

(4)四種咖啡實(shí)現(xiàn)類

/**
 * 深度烘焙咖啡類
 */
public class DarkRoast extends Beverage {

    public DarkRoast(){
        this.description = "DarkRoast";
    }

    @Override
    public double cost() {
        return 2.99;
    }
}
/**
 * 貓屎咖啡
 */

public class Decat extends Beverage {

    public Decat(){
        this.description = "Decat";
    }

    @Override
    public double cost() {
        return 1.89;
    }
}
/**
 * 濃縮咖啡類
 */
public class Espresso extends Beverage {

    public Espresso(){
        this.description = "Espresso";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}
/**
 * 首選咖啡(星巴克咖啡名)
 */
public class HouseBlend extends Beverage {
    public HouseBlend() {
        description = "HouseBlend";
    }

    @Override
    public double cost() {
        return 0.89;
    }
}

(5)調(diào)料類

/**
 * 摩卡  調(diào)料類
 */
public class Mocha extends CondimentDecorator {
    private Beverage beverage;

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

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

    @Override
    public double cost() {
        return .20 + beverage.cost();
    }
}
/**
 * 大豆  調(diào)料類
 */
public class Soy extends CondimentDecorator {
    private Beverage beverage;

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

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

    @Override
    public double cost() {
        return .30 + beverage.cost();
    }
}
/**
 * 鮮奶  調(diào)料類
 */
public class Whip extends CondimentDecorator {
    private Beverage beverage;

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

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

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

(6)容量類

/**
 * 大杯
 */
public class Big extends Capacity {
    private Beverage beverage;

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

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

    @Override
    public String getDescription() {
        return beverage.getDescription() + " ,Big";
    }
}
/**
 * 中杯
 */

public class Medium extends Capacity {
    private Beverage beverage;

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

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

    @Override
    public String getDescription() {
        return this.beverage.getDescription() + " ,Medium";
    }
}
/**
 * 小杯
 */

public class Small extends Capacity {
    private Beverage beverage;

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

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

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

(7)測試類

public class StarbuzzCoffee {
    public static void main(String[] args) {
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());

        Beverage beverage1 = new DarkRoast();
        beverage1 = new Mocha(beverage1);
        beverage1 = new Mocha(beverage1);
        beverage1 = new Whip(beverage1);
        System.out.println(beverage1.getDescription() + " $" + beverage1.cost());

        Beverage beverage2 = new HouseBlend();
        beverage2 = new Soy(beverage2);
        beverage2 = new Mocha(beverage2);
        beverage2 = new Whip(beverage2);
        beverage2 = new Big(beverage2);
        System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
    }
}

結(jié)果:

Espresso $1.99
DarkRoast,Mocha,Mocha,Whip $3.8900000000000006
HouseBlend,Soy,Mocha,Whip ,Big $2.09
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冠桃,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子道宅,更是在濱河造成了極大的恐慌食听,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件污茵,死亡現(xiàn)場離奇詭異樱报,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)省咨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門肃弟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人零蓉,你說我怎么就攤上這事笤受。” “怎么了敌蜂?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵箩兽,是天一觀的道長。 經(jīng)常有香客問我章喉,道長汗贫,這世上最難降的妖魔是什么身坐? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮落包,結(jié)果婚禮上部蛇,老公的妹妹穿的比我還像新娘。我一直安慰自己咐蝇,他們只是感情好涯鲁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著有序,像睡著了一般抹腿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旭寿,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天警绩,我揣著相機(jī)與錄音,去河邊找鬼盅称。 笑死肩祥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的微渠。 我是一名探鬼主播搭幻,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼逞盆!你這毒婦竟也來了檀蹋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤云芦,失蹤者是張志新(化名)和其女友劉穎俯逾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舅逸,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡桌肴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了琉历。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坠七。...
    茶點(diǎn)故事閱讀 39,965評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖旗笔,靈堂內(nèi)的尸體忽然破棺而出彪置,到底是詐尸還是另有隱情,我是刑警寧澤蝇恶,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布拳魁,位于F島的核電站,受9級特大地震影響撮弧,放射性物質(zhì)發(fā)生泄漏潘懊。R本人自食惡果不足惜姚糊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望授舟。 院中可真熱鬧救恨,春花似錦、人聲如沸岂却。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽躏哩。三九已至,卻和暖如春揉燃,著一層夾襖步出監(jiān)牢的瞬間扫尺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工炊汤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留正驻,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓抢腐,卻偏偏與公主長得像姑曙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子迈倍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容