java23種設計模式之十一:裝飾者模式
阿新 • • 發佈:2021-09-28
一.應用場景
如果你在遇到需要動態的給一個物件增加新的屬性(變數)和行為(方法),而這些屬性和行為又在一個獨立的類中,那麼,你可以瞭解一下裝飾者模式。
優點:可以更方便、更靈活的為一個物件動態的增加功能和屬性,如果用生成子類的方法,會造成類膨脹
並且還會產生很多冗餘程式碼。
缺點:需要你細細體會和深入瞭解
二.名詞解釋
1.Component(主體類:被裝飾物件的基類)
定義一個抽象類或介面,定義一些屬性和行為
2.ConcreteComponent(主體實現類:具體被裝飾物件)
定義一個類,繼承或實現主體類中的屬性和行為。
3.Decorator(裝飾類)
定義一個裝飾者類,新增一個主體類的屬性,並實現或定義一個與主體類介面一致的介面。
4.ConcreteDecorator(裝飾實現類1)
定義一個類,繼承裝飾者類,可以在內部封裝具體的屬性和行為,增加具體的功能。
三.需求
我想喝一杯飲料:
1.一杯咖啡,可以加牛奶、加巧克力
2.一杯奶茶,可以加牛奶、加巧克力
四.UML類圖
五.示例
1.主體類
package com.zpb.decorate; /** * @author pengbo.zhao * @description 飲品-被裝飾類 * @createDate 2021/9/27 10:28 * @updateDate 2021/9/27 10:28 * @version 1.0*/ public abstract class AbstractDrink { /** * 飲品名稱 */ public String name; /** * 飲品價格 */ public float price; /** * 飲品描述 */ public String description; /** * 花費多少錢 * @return float */ public abstract float cost(); public String getName() {return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } }
2.主體實現類
package com.zpb.decorate; /** * @author pengbo.zhao * @description 咖啡-單品 * @createDate 2021/9/27 10:31 * @updateDate 2021/9/27 10:31 * @version 1.0 */ public class Coffee extends AbstractDrink { @Override public float cost() { return super.getPrice(); } @Override public String getDescription() { return description + " 消費:" + cost() + "元"; } }
3.裝飾類
package com.zpb.decorate; /** * @author pengbo.zhao * @description 裝飾者-飲品 * @createDate 2021/9/27 10:35 * @updateDate 2021/9/27 10:35 * @version 1.0 */ public class DecoratorDrink extends AbstractDrink { public final AbstractDrink drink; public DecoratorDrink(AbstractDrink drink) { this.drink = drink; } @Override public float cost() { return super.getPrice() + drink.cost(); } @Override public String getDescription() { return description + " 消費:" + cost()+ "元"; } }
4.裝飾類實現一
package com.zpb.decorate; /** * @author pengbo.zhao * @description 巧克力 * @createDate 2021/9/28 10:25 * @updateDate 2021/9/28 10:25 * @version 1.0 */ public class Chocolate extends DecoratorDrink{ public Chocolate(AbstractDrink drink) { super(drink); setName("巧克力"); setPrice(5.0f); } }
5.裝飾類實現二
package com.zpb.decorate; /** * @author pengbo.zhao * @description 牛奶咖啡 * @createDate 2021/9/27 11:36 * @updateDate 2021/9/27 11:36 * @version 1.0 */ public class MilkCoffee extends DecoratorDrink { public MilkCoffee(AbstractDrink drink) { super(drink); } }
6.測試類
package com.zpb.decorate; /** * @author pengbo.zhao * @description 咖啡-測試類 * @createDate 2021/9/27 11:40 * @updateDate 2021/9/27 11:40 * @version 1.0 */ public class CoffeeTest { public static void main(String[] args) { // 咖啡單品 Coffee coffee = new Coffee(); coffee.setName("咖啡"); coffee.setPrice(10.f); coffee.setDescription("單品咖啡"); System.err.println(coffee.getDescription()); // 咖啡 + 牛奶 MilkCoffee milkCoffee = new MilkCoffee(coffee); milkCoffee.setName("牛奶"); milkCoffee.setPrice(3.0f); milkCoffee.setDescription("單品咖啡 + 牛奶"); System.err.println(milkCoffee.getDescription()); // 咖啡 + 牛奶 + 巧克力 Chocolate chocolate = new Chocolate(milkCoffee); chocolate.setName("巧克力"); chocolate.setPrice(5.0f); chocolate.setDescription("單品咖啡 + 牛奶 + 巧克力"); System.err.println(chocolate.getDescription()); } } // 輸出結果 // 單品咖啡 消費:10.0元 // 單品咖啡 + 牛奶 消費:13.0元 // 單品咖啡 + 牛奶 + 巧克力 消費:18.0元
六.總結
通過示例,我們通過咖啡這個單品,來不斷增加咖啡這個類的屬性,當然,我們也可以通過產生新的主體實現類,通過已有的裝飾者實現類來增強屬性。
由於本人是自己學習總結出來的,有不足之處,請各位看官批評指出,我將及時改正,以提高知識總結的正確性和嚴謹性,為大家學習提供方便!!! 如若轉載,請註明出處!!!