zoukankan      html  css  js  c++  java
  • 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元

    六.总结

    通过示例,我们通过咖啡这个单品,来不断增加咖啡这个类的属性,当然,我们也可以通过产生新的主体实现类,通过已有的装饰者实现类来增强属性。

     

     

     

     

     

    由于本人是自己学习总结出来的,有不足之处,请各位看官批评指出,我将及时改正,以提高知识总结的正确性和严谨性,为大家学习提供方便!!! 如若转载,请注明出处!!!
  • 相关阅读:
    JavaScript专题——专题三 JavaScript 面向对象
    写在2012结尾,2013的开始
    jQuery层次选择器
    jQuery内容过滤选择器
    使用Storm实现实时大数据分析
    jQuery表单选择器
    JavaScript专题——专题四 JavaScript DOM
    精通CSS+DIV网页样式与布局——CSS文字效果
    JavaScript专题——专题二 JavaScript语法
    牛腩JavaScript
  • 原文地址:https://www.cnblogs.com/MrRightZhao/p/15348944.html
Copyright © 2011-2022 走看看