zoukankan      html  css  js  c++  java
  • 三分钟带您搞懂装饰模式

    全文:959字,预计阅读时间:8分钟

    定义:

      装饰模式(Decorator)动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式比生成子类更加灵活。
      这里可以举一个生活中的例子,一个蛋糕,在蛋糕上摆上水果,这个蛋糕就变成了水果蛋糕,给这个水果蛋糕插上蜡烛,它就变成了一个生日蛋糕。(这是Head First中的一个例子,个人觉得非常的形象,记忆犹新)。

    分析:

      如果我们需要扩展一个类的功能,你会怎么做呢?如果直接修改这个类,我们就违反了开闭原则(对修改关闭,对扩展开放)。
      我们可以继承这个类,写一个这个类的子类,用于实现扩展功能,也可以使用组合(将这个类作为成员变量),达到相同的效果。
      我们将继承这种关系称为is-a,组合这种关系称为use-a。is-a的耦合程度要高于use-a,所以我们经常可以听到这样的说法:组合优于继承,原因就是这两种关系的耦合程度不同。
      装饰模式的核心思想,其实就是用组合代替继承。

    图解:

      这里可以看出,装饰者模式的特点是,装饰者实现了被装饰对象的接口,同时又将被装饰对象作为了成员变量

    实例:

      这里举一个咖啡店的例子,咖啡的原料是咖啡豆,我们可以使用咖啡豆和牛奶、蜂蜜、摩卡组合出不同价格、不同口味的咖啡。
      这里咖啡豆就是被装饰的对象,也就是图示中的ConcreteComponent,饮品类就是我们抽象出的Component,定义了展示价格和材料两个方法。牛奶、蜂蜜、摩卡是装饰对象,也就是图中的ConcreteDecoratorA、ConcreteDecoratorB。他们抽象出的Decorator,同样定义了展示价格和材料两个方法,具体类图与实现如下:

    代码:

    /**
     * 饮品.
     *
     * @author jialin.li
     * @date 2019-12-26 22:58
     */
    public interface Beverage {
        /** 获取描述 */
        String getDescription();
        /** 获取金额 */
        double getPrice();
    }
    /**
     * 咖啡豆1
     *
     * @author jialin.li
     * @date 2019-12-26 22:59
     */
    public class CoffeeBean1 implements Beverage {
    
        @Override
        public String getDescription() {
            return "第一种咖啡豆";
        }
    
        @Override
        public double getPrice() {
            return 10d;
        }
    }
    /**
     * 咖啡豆2
     *
     * @author jialin.li
     * @date 2019-12-26 23:00
     */
    public class CoffeeBean2 implements Beverage{
        @Override
        public String getDescription() {
            return "第一种咖啡豆";
        }
    
        @Override
        public double getPrice() {
            return 12.5d;
        }
    }
    /**
     * 装饰器.
     *
     * @author jialin.li
     * @date 2019-12-26 23:02
     */
    public class Decorator implements Beverage{
    
        protected Beverage coffee;
    
        @Override
        public String getDescription() {
            return "装饰器,由子类重写方法";
        }
    
        @Override
        public double getPrice() {
            return 0;
        }
    }
    /**
     * 蜂蜜.
     *
     * @author jialin.li
     * @date 2019-12-26 23:07
     */
    public class Honey extends Decorator {
        public Honey(Beverage coffee) {
            this.coffee = coffee;
        }
    
        @Override
        public String getDescription() {
            return coffee.getDescription() + "加蜂蜜";
        }
    
        @Override
        public double getPrice() {
            return coffee.getPrice() + 4.5d;
        }
    }
    /**
     * 牛奶.
     *
     * @author jialin.li
     * @date 2019-12-26 23:03
     */
    public class Milk extends Decorator {
        public Milk(Beverage coffee) {
            this.coffee = coffee;
        }
    
        @Override
        public String getDescription() {
            return coffee.getDescription() + "加牛奶";
        }
    
        @Override
        public double getPrice() {
            return coffee.getPrice() + 1.5d;
        }
    }
    /**
     * 摩卡.
     *
     * @author jialin.li
     * @date 2019-12-26 23:05
     */
    public class Mocha extends Decorator {
        public Mocha(Beverage coffee) {
            this.coffee = coffee;
        }
    
        @Override
        public String getDescription() {
            return coffee.getDescription() + "加摩卡";
        }
    
        @Override
        public double getPrice() {
            return coffee.getPrice() + 2.5d;
        }
    }
    /**
     * 测试类.
     *
     * @author jialin.li
     * @date 2019-12-26 23:09
     */
    public class Main {
        public static void main(String[] args) {
            CoffeeBean1 coffee1 = new CoffeeBean1();
            CoffeeBean2 coffee2 = new CoffeeBean2();
    
            // 加蜂蜜
            Beverage honey = new Honey(coffee1);
            // 加摩卡
            Beverage mocha = new Mocha(honey);
            System.out.println(mocha.getDescription());
            System.out.println(mocha.getPrice());
    
            // 加牛奶
            Milk milk = new Milk(coffee2);
            System.out.println(milk.getDescription());
            System.out.println(milk.getPrice());
        }
    }

    结果:

      第一种咖啡豆加蜂蜜加摩卡
      17.0
      第一种咖啡豆加牛奶
      14.0

  • 相关阅读:
    送给热爱书法的朋友们
    [原创]中秋随笔 祝大家中秋快乐
    Comsenz力邀您的加盟
    夜半冻醒有感
    Comsenz力邀您的加盟
    成熟的谷子先低头
    [转载]10个经典的web2.0配色方案网站
    无法嵌入互操作类型“Microsoft.Office.Interop.Excel.ApplicationClass”
    C#获取真实IP地址及分析
    使用TRY CATCH进行SQL Server异常处理
  • 原文地址:https://www.cnblogs.com/nedulee/p/12105111.html
Copyright © 2011-2022 走看看