《Head First 设计模式》(三):装饰者模式
生活随笔
收集整理的這篇文章主要介紹了
《Head First 设计模式》(三):装饰者模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1. 簡介
裝飾器模式(Decorator
Pattern) :允許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬于結構型模式,它是作為現有的類的一個包裝。
這種模式創建了一個裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供了額外的功能。
2. 范例:咖啡店
剛開始時,咖啡店的程序設計是:
- 一個咖啡飲料的父類 Beverage,抽象類,店里的所有飲料都必須繼承此父類
- 不同種類的咖啡飲料都是一個類(都需要繼承 Beverage類)
帶來的問題:
購買咖啡飲料時,客戶可以要求加入不同中類的配料,如:摩卡、奶泡…
此時的咖啡店的程序設計是:
3. 優化方案:實例變量和繼承
Beverage類優化:
Beverage類中新增表示各種調料的實例變量
咖啡飲料類:
帶來的問題:
- 調料價格的改變需要修改代碼
- 新增調料需要改變Beverage類的 cost()方法
- …
設計原則:類應該對擴展開放,對修改關閉
4. 優化方案:裝飾者模式
以咖啡飲料為主體,然后在運行時以調料來裝飾(decorate)咖啡飲料。比如,如果顧客想要摩卡和奶泡深培咖啡,那么,做法是:
做法圖解:
2. 顧客想要摩卡(Mocha)調料,所以建立一個Mocha對象,并用它將DarkRoast對象包(wrap)起來
3. 顧客想要奶泡(Whip),所以建立一個Whip裝飾者,并將它Mocha對象包起來
4. 計算總價錢,調用最外層的裝飾者(Whip)的cost()方法就可以計算出總價錢。Whip的cost()方法會委托它裝飾的對象,即Mocha,計算出價錢,然后再加上奶泡的價錢
3.1 代碼
Beverage類:
package com.jbp.designpattern.decorate;/*** @ClassName: Beverage* @description: 咖啡飲料父類* @author: JiangBeiPing* @create: 2021-06-29 15:53* @Version: 1.0**/ public abstract class Beverage {String description = "咖啡飲料父類";public String getDescription() {return description;}public abstract double cost(); }咖啡飲料類:
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;} }調料類:
package com.jbp.designpattern.decorate;/*** @ClassName: Condiment* @description: 調料* @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對象能夠引用一個Beverage* 用一個實例變量記錄飲料,即被裝飾者* 讓被裝飾者(飲料)被記錄到實例變量中(此處做法是:把飲料作為構造器的參數,再由構造器將此飲料記錄在實例變量中)*/Beverage beverage;public Mocha(Beverage beverage) {this.beverage = beverage;}@Overridepublic double cost() {// 計算帶Mocha的咖啡飲料的價錢:Mocha的價錢 + 咖啡飲料的價錢return 0.5 + beverage.cost();}@Overridepublic String getDescription() {return beverage.getDescription() + ",摩卡";} } package com.jbp.designpattern.decorate;/*** @ClassName: Whip* @description: 調料:奶泡* @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() + ",奶泡";} }測試:
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();//咖啡飲料:濃縮咖啡,價錢:1.99System.out.println("咖啡飲料:" + espresso.getDescription() + "," + "價錢:" + espresso.cost());Beverage houseBlend = new HouseBlend();// 加摩卡houseBlend = new Mocha(houseBlend);// 加奶泡houseBlend = new Whip(houseBlend);//咖啡飲料:混搭咖啡,摩卡,奶泡,價錢:2.8System.out.println("咖啡飲料:" + houseBlend.getDescription() + "," + "價錢:" + houseBlend.cost());} }3.2 總結
4. Java中的裝飾者模式
IO流API:
總結
以上是生活随笔為你收集整理的《Head First 设计模式》(三):装饰者模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数理逻辑习题集(6)
- 下一篇: 前端学习(2465):ajax发送请求