淺談設(shè)計(jì)模式3——裝飾模式


這個(gè)模式用做飯來(lái)說(shuō)確實(shí)感覺(jué)不錯(cuò),因?yàn)闀?shū)上也是這么打比方的忆畅,就是用咖啡衡未,還都是那么繞口的名字,感覺(jué)實(shí)在受不了家凯。所以此處用面條來(lái)打比方缓醋,原理相同,但我覺(jué)得這個(gè)應(yīng)該大家會(huì)更熟悉一些绊诲。

1送粱、背景
有各式各樣的面條,拉面掂之,手搟面抗俄,寬條面,面片等等板惑,當(dāng)然,每種面條由于制作工藝不同偎快,所以?xún)r(jià)錢(qián)也不一樣冯乘。同時(shí),面條還要配著鹵汁晒夹,湯料裆馒,所以可以加豬骨高湯,雞架高湯丐怯,蔬菜高湯喷好,羊肉湯,或者炸好的甜面醬读跷,西紅柿雞蛋醬等等梗搅。同樣,加不同的醬料,價(jià)錢(qián)也不同无切。

那么首先想到的是荡短,先做一個(gè)面條基類(lèi),然后從這個(gè)類(lèi)中派生出各種面條類(lèi)哆键,比如雞架高湯手搟面掘托,西紅柿雞蛋寬條面〖冢可是闪盔,一旦你這樣做了,將會(huì)出現(xiàn)以下問(wèn)題:
1)將會(huì)出現(xiàn)無(wú)窮多的子類(lèi)辱士,n種類(lèi)型的面條×m中類(lèi)型的鹵汁=m×n種類(lèi)型的產(chǎn)品(為了和不同形狀的面條區(qū)分泪掀,凡是上桌的都叫做“產(chǎn)品”)
2)無(wú)法多種材料進(jìn)行拼湊。比如你想吃拉面识补,配炸醬+蔬菜高湯族淮,那這種設(shè)計(jì)方法做不到,除非再新建一個(gè)類(lèi)凭涂,這樣無(wú)疑又增大了工作量祝辣。
3)無(wú)法修改價(jià)錢(qián)。目前物價(jià)越來(lái)越高切油,可能半年后蝙斜,西紅柿從原來(lái)的2塊一斤,漲到了4塊一斤澎胡,那么你必須修改所有加了鹵汁為西紅柿炒雞蛋的產(chǎn)品類(lèi)——估計(jì)累暈孕荠。

所以經(jīng)過(guò)上面問(wèn)題的討論,還是采用裝飾模式比較好攻谁。那么裝飾模式長(zhǎng)啥樣稚伍?不要走開(kāi),精彩繼續(xù)戚宦。

2个曙、裝飾模式
顧名思義,裝飾模式就是在原有的基礎(chǔ)上受楼,對(duì)原有的事物錦上添花垦搬。每次加一個(gè)裝飾,一方面擴(kuò)展了原有對(duì)象的特點(diǎn)艳汽,同時(shí)猴贰,原有對(duì)象的基本特質(zhì)保持不變。即咖啡再怎么變河狐,也還是咖啡米绕,無(wú)論你加了糖瑟捣、奶、豆?jié){义郑。面條也是蝶柿,你加什么鹵汁,湯料非驮,仍然還是面條交汤。只不過(guò)面條的味道變了,口感變了劫笙,價(jià)錢(qián)也變了芙扎。上代碼看下:


public class Test1 {

    public static void main(String args[])
    {
        /*寬條面西紅柿雞蛋面 2+2=4
         * 拉面羊肉湯面  3+3=6
         * 寬面條西紅柿雞蛋,羊肉湯面 2+2+3=7
         * */
        
            WideNoodles wideNoodles1=new WideNoodles();//2
            TomatoEgg tomatoEgg1=new TomatoEgg(wideNoodles1);//2
            
            WideNoodles wideNoodles2=new WideNoodles();//2
            TomatoEgg tomatoEgg2=new TomatoEgg(wideNoodles2);//2
            GoatSoup goatSoup2=new GoatSoup(tomatoEgg2);//3
            
            StretchNoodles stretchNoodles1=new StretchNoodles();//3
            GoatSoup goatSoup1=new GoatSoup(stretchNoodles1);//3
                        
        System.out.println(tomatoEgg1.getDes()+tomatoEgg1.price());
        System.out.println(goatSoup1.getDes()+goatSoup1.price());
        System.out.println(goatSoup2.getDes()+goatSoup2.price());
        
        
    }
}
abstract class Noodles //面條抽象類(lèi)
{
    protected String description="noodles";
    public abstract double price();
    public String getDes(){ return description; }
}

//各種面條
class WideNoodles extends Noodles//寬條面
{
    public WideNoodles() {this.description="WideNoodles";}
    public double price() {return 2.0;}
}

class StretchNoodles extends Noodles//拉面
{
    public StretchNoodles() {this.description="StretchNoodles";}
    public double price(){ return 3.0;}
}

//鹵汁類(lèi)
class Bittern extends Noodles////基本鹵汁
{
    protected Noodles noodles;//面條
    
    public Bittern(Noodles n){this.description="Bittern";  this.noodles=n;}//修改成鹵汁類(lèi)型
    public double price(){return this.noodles.price()+1.0;}//面條+1塊錢(qián)鹵汁   
    public String getDes() {return this.description+","+this.noodles.getDes();}//面條+鹵汁
}

//具體鹵汁填大,由于上面鹵汁基類(lèi)的方法都已經(jīng)重新戒洼,所以只需要修改price即可
class TomatoEgg extends Bittern//西紅柿炒雞蛋鹵汁
{
    public TomatoEgg(Noodles n) {super(n); this.description="TomatoEgg";}
    public double price(){return this.noodles.price()+2.0;}
}

class GoatSoup extends Bittern//羊肉湯鹵汁
{
    public GoatSoup(Noodles n) {super(n);this.description="GoatSoup";}
    public double price() {return this.noodles.price()+3.0;}
}
class ChickSoup extends Bittern//雞架鹵汁
{
    public ChickSoup(Noodles n) {super(n);this.description="ChickSoup";}
    public double price() {return this.noodles.price()+4.0;}
}

運(yùn)行結(jié)果截圖

開(kāi)始解析上面的代碼。剛看到工作的同學(xué)準(zhǔn)備招聘高級(jí)java程序員允华。讀研的傷不起啊圈浇。。靴寂。
1)從程序中可以看到磷蜀,所有的類(lèi)都有一個(gè)共同的抽象基類(lèi),即Noodles百炬,因?yàn)楫a(chǎn)品無(wú)論怎么變化褐隆,本質(zhì)是面條,也應(yīng)正了繼承是Is—a的規(guī)律剖踊。面條都有描述和價(jià)錢(qián)庶弃。
2)每一種面條都作為獨(dú)立的個(gè)體,而鹵汁不一樣德澈,鹵汁需要依附于面條歇攻,也就是有了面條,鹵汁才能修飾作為裝飾者梆造,去修飾面條缴守。所以鹵汁中包含了面條主體。而鹵汁+面條=面條澳窑,所以面條的本質(zhì)沒(méi)有變斧散。
(注意修飾和被修飾的關(guān)系供常,這樣才能確定組合的情況)

3摊聋、Java中的具體實(shí)現(xiàn)
在Java.io.*中,就是這樣的道理栈暇。所有的IO類(lèi)都有一個(gè)共同的基類(lèi)麻裁,表明這些類(lèi)都是I/O操作,本質(zhì)沒(méi)有變。但是煎源,對(duì)于真正做讀寫(xiě)操作的(就好像本文中的面條)色迂,作為一個(gè)獨(dú)立實(shí)體,這些類(lèi)只能一次讀取一個(gè)字節(jié)手销,或者一行歇僧。而修飾這些進(jìn)行實(shí)際讀寫(xiě)操作的裝飾者,則可能只是封裝了一個(gè)緩存锋拖,或者將讀取的字符轉(zhuǎn)換成小寫(xiě)等等诈悍。

4、其他方面
其實(shí)說(shuō)的再遠(yuǎn)一點(diǎn)兽埃。Unix中的管道也是這種思想侥钳,每個(gè)程序都提供了讀取數(shù)據(jù)和寫(xiě)出數(shù)據(jù)的接口,然后通過(guò)管道柄错,可以一次又一次的傳遞數(shù)據(jù)舷夺,比如:ls /root | more | grep "Noodles"。當(dāng)然售貌,more只是為了說(shuō)明给猾,實(shí)際沒(méi)啥用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末趁矾,一起剝皮案震驚了整個(gè)濱河市耙册,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌毫捣,老刑警劉巖详拙,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蔓同,居然都是意外死亡饶辙,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)斑粱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)弃揽,“玉大人,你說(shuō)我怎么就攤上這事则北】笪ⅲ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵尚揣,是天一觀的道長(zhǎng)涌矢。 經(jīng)常有香客問(wèn)我,道長(zhǎng)快骗,這世上最難降的妖魔是什么娜庇? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任塔次,我火速辦了婚禮,結(jié)果婚禮上名秀,老公的妹妹穿的比我還像新娘励负。我一直安慰自己,他們只是感情好匕得,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布继榆。 她就那樣靜靜地躺著,像睡著了一般汁掠。 火紅的嫁衣襯著肌膚如雪裕照。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天调塌,我揣著相機(jī)與錄音晋南,去河邊找鬼。 笑死羔砾,一個(gè)胖子當(dāng)著我的面吹牛负间,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播姜凄,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼政溃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了态秧?” 一聲冷哼從身側(cè)響起董虱,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎申鱼,沒(méi)想到半個(gè)月后愤诱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捐友,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年淫半,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匣砖。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡科吭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出猴鲫,到底是詐尸還是另有隱情对人,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布拂共,位于F島的核電站牺弄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏匣缘。R本人自食惡果不足惜猖闪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肌厨。 院中可真熱鬧培慌,春花似錦、人聲如沸柑爸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)表鳍。三九已至馅而,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間譬圣,已是汗流浹背瓮恭。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厘熟,地道東北人屯蹦。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像绳姨,于是被迫代替她去往敵國(guó)和親登澜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

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