国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

開發(fā)之路(設(shè)計(jì)模式三:裝飾者模式)

Vicky / 1390人閱讀

摘要:若要擴(kuò)展功能,裝飾者提供了比繼承更有彈性的替代方案。裝飾者模式意味著一群裝飾者類,這些類用來包裝具體組件。裝飾者類反映出被裝飾組件類型。裝飾者會(huì)導(dǎo)致設(shè)計(jì)中出現(xiàn)許多小對(duì)象,如果過度使用,會(huì)讓程序變得很復(fù)雜。

嘿嘿嘿,你是不是很喜歡用繼承呢?感覺沒什么事情是一個(gè)“爸爸”類搞不定的,有的話就兩個(gè),快來跟我看看這個(gè)模式吧,它能讓你“斷奶”,給愛用繼承的人一個(gè)全新的設(shè)計(jì)眼界。

直奔主題,你是否有聽說過組合呢?你是否覺得繼承往往有的時(shí)候沒你想象的那么好用呢?如果有,你又是否嘗試自己解決這個(gè)問題呢?讓我們來看個(gè)例子~~~~

假設(shè)我們有家咖啡店,設(shè)計(jì)如下
飲料(Beverage)基類,有4個(gè)子類,分別是綜合咖啡(HouseBlend),深焙咖啡 (DarkRoast),低咖啡因咖啡 (Decaf),(Espresso)濃縮咖啡,他們都是子類,繼承了cost支付方法。

嗯,看似目前沒啥問題,假設(shè)我需要改變點(diǎn)需求呢?
喝咖啡可以加各種各樣調(diào)料的,例如加牛奶,豆奶,摩卡,小餅干等等,而且每種飲料根據(jù)添加的調(diào)料不同還要再加對(duì)應(yīng)的調(diào)料費(fèi)用,那么這些使用繼承的話。。。。。??峙聲?huì)出現(xiàn)以下這樣的情況。。

想想以前這樣的設(shè)計(jì),是不是有種細(xì)思極恐的感覺。。

當(dāng)然聰明一點(diǎn)的會(huì)這樣設(shè)計(jì),這里我就不自己畫了,直接貼出來圖例

其實(shí)這樣的設(shè)計(jì)也非常有問題,跟上面"類爆炸"的設(shè)計(jì)沒啥區(qū)別,父類和子類依賴性太高了,低耦合。
1:假設(shè)我在父類中添加了新的調(diào)料,那么所有子類都需要相應(yīng)修改代碼,加大了工作量。
2:在父類中改變cost方法,子類也需要跟著改變。。

總之,太濫用繼承其實(shí)是給自己挖坑,繼承往往有的時(shí)候不能設(shè)計(jì)出彈性和易擴(kuò)展性的代碼。這里就要說說和繼承的“死對(duì)頭”-->組合,而裝飾者模式就充分運(yùn)用了組合

設(shè)計(jì)原則一:類應(yīng)該對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。
注:這個(gè)原則剛開始聽是感覺自相矛盾的,確實(shí)剛開始我也有這疑問,回過頭看看觀察者模式,通過加入新的“觀察者”就相當(dāng)于拓展開放了“主題”,而“主題”本身沒有改變代碼,對(duì)修改關(guān)閉了。不急請(qǐng)往下看。

依舊以咖啡店做例子
這里改變做法,以飲料為主體,然后用調(diào)料“裝飾”飲料,
打個(gè)比方:如果顧客想要摩卡和奶泡深焙咖啡,要做的是:
1:拿一個(gè)深焙咖啡(HouseBlend)對(duì)象
2:以摩卡(Mocha)對(duì)象“裝飾”它
3:以奶泡(Whip)對(duì)象“裝飾”它
4:調(diào)用cost()方法,并依賴委托將調(diào)料價(jià)錢加上去
過程流程圖如下(請(qǐng)多看幾遍)

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

放出裝飾者模型的類圖(重點(diǎn)看)

然后下面是基于此模式下的咖啡店的類圖

是不是感覺這個(gè)設(shè)計(jì)煥然一新。
下面我要好好打造我的咖啡店了

飲料抽象類

package Beverage;
/**
 * 飲料抽象類
 * 被裝飾者類
 * @author Joy
 *
 */
public abstract class Beverage {
    //飲料名稱初始化
    String description="未知飲料";

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    //價(jià)錢方法抽象化,不需要具體實(shí)現(xiàn)
    public abstract double cost();
}

下面是四個(gè)咖啡類

package Beverage;

/**
 * 深焙咖啡 
 * 
 * @author Joy
 * 
 */
public class DarkRoast extends Beverage {
    public DarkRoast() {
        description = "深焙咖啡";
    }

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

}
package Beverage;

/**
 * 低咖啡因咖啡 
 * 
 * 
 * 
 */
public class Decaf extends Beverage {

    public Decaf() {
        description = "低咖啡因咖啡";
    }

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

}
package Beverage;
/**
 * 
 * 濃縮咖啡類
 * 
 *
 */

//繼承飲料父類,因?yàn)樗秋嬃弦环N
public class Espresso extends Beverage {
    //寫一個(gè)構(gòu)造器,將飲料名稱重定義
    public Espresso() {
        description="濃縮咖啡";
    }

    //最后計(jì)算濃縮咖啡價(jià)格,先不算調(diào)料價(jià)錢,一杯濃縮咖啡1.99
    @Override
    public double cost() {        
        return 1.99;
    }

}
    package Beverage;
/**
 * 綜合咖啡類
 * 
 *
 */
public class HouseBlend extends Beverage {
    public HouseBlend() {
        description = "綜合咖啡";
    }

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

}

調(diào)料抽象類

package Condiment;

import Beverage.Beverage;

/**
 * 調(diào)料抽象類 裝飾者類
 * 
 * @author Joy
 * 
 */
public abstract class CondimentDecorator extends Beverage {
    // 描述
    public abstract String getDescription();

}

下面是具體調(diào)料實(shí)現(xiàn)類

package Condiment;

import Beverage.Beverage;

/**
 * 摩卡類,裝飾者
 * 
 * @author Joy
 * 
 */
// 摩卡是一個(gè)裝飾者,讓它繼承裝飾者父類
public class Mocha extends CondimentDecorator {

    // 設(shè)定飲料變量記錄飲料,也就是被裝飾者
    Beverage beverage;

    // 設(shè)置構(gòu)造器將被裝飾者(飲料)被記錄到實(shí)例變量beverage中
    // 把飲料設(shè)置構(gòu)造器參數(shù),再有構(gòu)造器將此記錄到實(shí)例變量中
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    // 重寫方法,將其飲料描述加上添加的調(diào)料
    @Override
    public String getDescription() {
        return beverage.getDescription() + ",加摩卡";
    }

    // 重寫方法,將飲料價(jià)錢+調(diào)料價(jià)錢
    @Override
    public double cost() {
        return beverage.cost() + 0.2;
    }

}
package Condiment;

import Beverage.Beverage;

/**
 * 豆?jié){類,裝飾者
 * 內(nèi)容與前面摩卡一樣
 * @author Joy
 *
 */
public class Soy extends CondimentDecorator {

    Beverage beverage;
    
    public Soy(Beverage beverage) {
    this.beverage=beverage;
    }
    
    @Override
    public String getDescription() {    
        return beverage.getDescription()+",加豆?jié){";
    }

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

}
package Condiment;

import Beverage.Beverage;

/**
 * 奶泡類,裝飾者 內(nèi)容與前面摩卡一樣
 * 
 * @author Joy
 * 
 */
public class Whip extends CondimentDecorator {
    Beverage beverage;

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

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

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

}

測(cè)試類

package TestMain;

import java.math.BigDecimal;

import Beverage.Beverage;
import Beverage.DarkRoast;
import Beverage.Espresso;
import Beverage.HouseBlend;
import Condiment.Mocha;
import Condiment.Soy;
import Condiment.Whip;

public class TestMain {
    public static void main(String[] args) {
        //要一杯濃縮咖啡,什么調(diào)料都不加
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + "	$" + beverage.cost());
        
        //要一杯深焙咖啡        
        Beverage beverage2=new DarkRoast();
        //加兩份摩卡
        beverage2=new Mocha(beverage2);
        beverage2=new Mocha(beverage2);
        //加一份奶泡
        beverage2=new Whip(beverage2);
        System.out.println(beverage2.getDescription()+"	$"+beverage2.cost());
        
        //要一杯加豆?jié){,加摩卡,加奶泡的綜合咖啡
        Beverage beverage3=new HouseBlend();
        beverage3=new Whip(beverage3);
        beverage3=new Mocha(beverage3);
        beverage3=new Soy(beverage3);
        //這里對(duì)價(jià)錢保留兩位小數(shù)四舍五入
        double money=beverage3.cost();
        BigDecimal b=new BigDecimal(money);
        double f1=b.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
        System.out.println(beverage3.getDescription()+"	$"+f1);
    }
}

效果圖:

要點(diǎn):
1:繼承屬于擴(kuò)展形式一種,但不見的是達(dá)到彈性設(shè)計(jì)的最佳方式,組合優(yōu)于繼承。
2:應(yīng)該允許行為可以被拓展,而無需修改現(xiàn)有的代碼。
3:裝飾者模式意味著一群裝飾者類,這些類用來包裝具體組件。
4:裝飾者類反映出被裝飾組件類型。
5:可以使用無數(shù)個(gè)裝飾者包裝一個(gè)組件。
6:裝飾者會(huì)導(dǎo)致設(shè)計(jì)中出現(xiàn)許多小對(duì)象,如果過度使用,會(huì)讓程序變得很復(fù)雜。

裝飾者模式結(jié)束,這個(gè)模式是個(gè)很有用的模式,可以說是提高代碼素養(yǎng)的關(guān)鍵一步,模擬代碼已經(jīng)全部放出,注釋也寫的比較清楚,若有不理解歡迎留言。

感謝你看到這里,裝飾者模式部分結(jié)束,本人文筆隨便,若有不足或錯(cuò)誤之處望給予指點(diǎn),90度彎腰~很快我會(huì)發(fā)布下一個(gè)設(shè)計(jì)模式內(nèi)容,生命不息,編程不止!

參考書籍:《Head First 設(shè)計(jì)模式》
參考網(wǎng)站:
Java中的繼承與組合:http://www.importnew.com/12907.html

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/70184.html

相關(guān)文章

  • 我的Java設(shè)計(jì)模式-代理模式

    摘要:下面總結(jié)了它倆的異同相同點(diǎn)都需要實(shí)現(xiàn)同一個(gè)接口或者繼承同一個(gè)抽象類,并且代理角色和裝飾角色都持有被代理角色和構(gòu)件角色的引用。 寫完上一篇之后有小伙伴問我有沒有寫過代理模式,想看看我的理解。原本我的設(shè)計(jì)模式系列是按照創(chuàng)建型-行為型-結(jié)構(gòu)型的順序?qū)懴氯サ?,既然小伙伴誠(chéng)心誠(chéng)意了,我就大發(fā)慈悲的穿插一篇代理模式。開玩笑,題外話。 說起代理模式,就不由得想起經(jīng)紀(jì)人,說起經(jīng)紀(jì)人,就想起了...對(duì),...

    BWrong 評(píng)論0 收藏0
  • JS設(shè)計(jì)模式--裝飾模式

    摘要:當(dāng)接口比較多,裝飾器也比較多時(shí),可以獨(dú)立抽取一個(gè)裝飾器父類,實(shí)現(xiàn)目標(biāo)類的所有接口,再創(chuàng)建真正的裝飾器來繼承這個(gè)父類。四的實(shí)現(xiàn)方式提供了一種類似的注解的語法糖,來實(shí)現(xiàn)裝飾者模式。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 所謂裝飾者模式,就是動(dòng)態(tài)的給類或?qū)ο笤黾勇氊?zé)的設(shè)計(jì)模式。它...

    wmui 評(píng)論0 收藏0
  • Java 設(shè)計(jì)模式裝飾模式

    摘要:裝飾者模式組成結(jié)構(gòu)抽象構(gòu)件給出抽象接口或抽象類,以規(guī)范準(zhǔn)備接收附加功能的對(duì)象。裝飾者模式圖解裝飾者模式應(yīng)用場(chǎng)景需要擴(kuò)展一個(gè)類的功能,或給一個(gè)類添加附加職責(zé)。裝飾者對(duì)象接受所有來自客戶端的請(qǐng)求。參考資料設(shè)計(jì)模式 一、了解裝飾者模式 1.1 什么是裝飾者模式 裝飾者模式指的是在不必改變?cè)愇募褪褂美^承的情況下,動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對(duì)象的功能。它是通過創(chuàng)建一個(gè)包裝對(duì)象,也就是裝飾者來包裹真實(shí)的對(duì)...

    kumfo 評(píng)論0 收藏0
  • php設(shè)計(jì)模式

    摘要:我們今天也來做一個(gè)萬能遙控器設(shè)計(jì)模式適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。今天要介紹的仍然是創(chuàng)建型設(shè)計(jì)模式的一種建造者模式。設(shè)計(jì)模式的理論知識(shí)固然重要,但 計(jì)算機(jī)程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計(jì)模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對(duì)容器接口對(duì)象進(jìn)行操作,第二類是返回一個(gè)容器接口對(duì)象,上節(jié)我們介紹了...

    Dionysus_go 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<