《Head First 设计模式》(三):装饰者模式
1. 簡(jiǎn)介
裝飾器模式(Decorator
Pattern) :允許向一個(gè)現(xiàn)有的對(duì)象添加新的功能,同時(shí)又不改變其結(jié)構(gòu)。這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它是作為現(xiàn)有的類(lèi)的一個(gè)包裝。
這種模式創(chuàng)建了一個(gè)裝飾類(lèi),用來(lái)包裝原有的類(lèi),并在保持類(lèi)方法簽名完整性的前提下,提供了額外的功能。
2. 范例:咖啡店
剛開(kāi)始時(shí),咖啡店的程序設(shè)計(jì)是:
- 一個(gè)咖啡飲料的父類(lèi) Beverage,抽象類(lèi),店里的所有飲料都必須繼承此父類(lèi)
- 不同種類(lèi)的咖啡飲料都是一個(gè)類(lèi)(都需要繼承 Beverage類(lèi))
帶來(lái)的問(wèn)題:
購(gòu)買(mǎi)咖啡飲料時(shí),客戶可以要求加入不同中類(lèi)的配料,如:摩卡、奶泡…
此時(shí)的咖啡店的程序設(shè)計(jì)是:
3. 優(yōu)化方案:實(shí)例變量和繼承
Beverage類(lèi)優(yōu)化:
Beverage類(lèi)中新增表示各種調(diào)料的實(shí)例變量
咖啡飲料類(lèi):
帶來(lái)的問(wèn)題:
- 調(diào)料價(jià)格的改變需要修改代碼
- 新增調(diào)料需要改變Beverage類(lèi)的 cost()方法
- …
設(shè)計(jì)原則:類(lèi)應(yīng)該對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉
4. 優(yōu)化方案:裝飾者模式
以咖啡飲料為主體,然后在運(yùn)行時(shí)以調(diào)料來(lái)裝飾(decorate)咖啡飲料。比如,如果顧客想要摩卡和奶泡深培咖啡,那么,做法是:
做法圖解:
2. 顧客想要摩卡(Mocha)調(diào)料,所以建立一個(gè)Mocha對(duì)象,并用它將DarkRoast對(duì)象包(wrap)起來(lái)
3. 顧客想要奶泡(Whip),所以建立一個(gè)Whip裝飾者,并將它Mocha對(duì)象包起來(lái)
4. 計(jì)算總價(jià)錢(qián),調(diào)用最外層的裝飾者(Whip)的cost()方法就可以計(jì)算出總價(jià)錢(qián)。Whip的cost()方法會(huì)委托它裝飾的對(duì)象,即Mocha,計(jì)算出價(jià)錢(qián),然后再加上奶泡的價(jià)錢(qián)
3.1 代碼
Beverage類(lèi):
package com.jbp.designpattern.decorate;/*** @ClassName: Beverage* @description: 咖啡飲料父類(lèi)* @author: JiangBeiPing* @create: 2021-06-29 15:53* @Version: 1.0**/ public abstract class Beverage {String description = "咖啡飲料父類(lèi)";public String getDescription() {return description;}public abstract double cost(); }咖啡飲料類(lèi):
package com.jbp.designpattern.decorate;/*** @ClassName: Espresso* @description: 濃縮咖啡* @author: JiangBeiPing* @create: 2021-06-29 15:59* @Version: 1.0**/ public class Espresso extends Beverage{public Espresso() {description = "濃縮咖啡";}@Overridepublic double cost() {return 1.99;} } package com.jbp.designpattern.decorate;/*** @ClassName: HouseBlend* @description: 混搭咖啡* @author: JiangBeiPing* @create: 2021-06-29 16:02* @Version: 1.0**/ public class HouseBlend extends Beverage{public HouseBlend() {description = "混搭咖啡";}@Overridepublic double cost() {return 1.5;} }調(diào)料類(lèi):
package com.jbp.designpattern.decorate;/*** @ClassName: Condiment* @description: 調(diào)料* @author: JiangBeiPing* @create: 2021-06-29 15:55* @Version: 1.0**/ public abstract class CondimentDecorate extends Beverage {@Overridepublic abstract String getDescription();} package com.jbp.designpattern.decorate;/*** @ClassName: Mocha* @description: 摩卡* @author: JiangBeiPing* @create: 2021-06-29 16:03* @Version: 1.0**/ public class Mocha extends CondimentDecorate{/*** 讓Mocha對(duì)象能夠引用一個(gè)Beverage* 用一個(gè)實(shí)例變量記錄飲料,即被裝飾者* 讓被裝飾者(飲料)被記錄到實(shí)例變量中(此處做法是:把飲料作為構(gòu)造器的參數(shù),再由構(gòu)造器將此飲料記錄在實(shí)例變量中)*/Beverage beverage;public Mocha(Beverage beverage) {this.beverage = beverage;}@Overridepublic double cost() {// 計(jì)算帶Mocha的咖啡飲料的價(jià)錢(qián):Mocha的價(jià)錢(qián) + 咖啡飲料的價(jià)錢(qián)return 0.5 + beverage.cost();}@Overridepublic String getDescription() {return beverage.getDescription() + ",摩卡";} } package com.jbp.designpattern.decorate;/*** @ClassName: Whip* @description: 調(diào)料:奶泡* @author: JiangBeiPing* @create: 2021-06-29 16:29* @Version: 1.0**/ public class Whip extends CondimentDecorate{Beverage beverage;public Whip(Beverage beverage) {this.beverage = beverage;}@Overridepublic double cost() {return 0.8 + beverage.cost();}@Overridepublic String getDescription() {return beverage.getDescription() + ",奶泡";} }測(cè)試:
package com.jbp.designpattern.decorate;/*** @ClassName: Test* @description:* @author: JiangBeiPing* @create: 2021-06-29 16:13* @Version: 1.0**/ public class Test {public static void main(String[] args) {Beverage espresso = new Espresso();//咖啡飲料:濃縮咖啡,價(jià)錢(qián):1.99System.out.println("咖啡飲料:" + espresso.getDescription() + "," + "價(jià)錢(qián):" + espresso.cost());Beverage houseBlend = new HouseBlend();// 加摩卡houseBlend = new Mocha(houseBlend);// 加奶泡houseBlend = new Whip(houseBlend);//咖啡飲料:混搭咖啡,摩卡,奶泡,價(jià)錢(qián):2.8System.out.println("咖啡飲料:" + houseBlend.getDescription() + "," + "價(jià)錢(qián):" + houseBlend.cost());} }3.2 總結(jié)
4. Java中的裝飾者模式
IO流API:
總結(jié)
以上是生活随笔為你收集整理的《Head First 设计模式》(三):装饰者模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 数理逻辑习题集(6)
- 下一篇: Head First设计模式(中文版)P