java23种设计模式之十一:装饰者模式
一.应用场景
如果你在遇到需要动态的给一个对象增加新的属性(变量)和行为(方法),而这些属性和行为又在一个独立的类中,那么,你可以了解一下装饰者模式。
优点:可以更方便、更灵活的为一个对象动态的增加功能和属性,如果用生成子类的方法,会造成类膨胀
并且还会产生很多冗余代码。
缺点:需要你细细体会和深入了解
二.名词解释
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元
六.总结
通过示例,我们通过咖啡这个单品,来不断增加咖啡这个类的属性,当然,我们也可以通过产生新的主体实现类,通过已有的装饰者实现类来增强属性。
由于本人是自己学习总结出来的,有不足之处,请各位看官批评指出,我将及时改正,以提高知识总结的正确性和严谨性,为大家学习提供方便!!!
如若转载,请注明出处!!!