zoukankan      html  css  js  c++  java
  • 装饰者模式(包装模式)

    应用场景:老王是卖豆浆的,现在的豆浆品种不断增多,如下图,可以任意搭配,这种情况如果用继承的方式会形成 类爆炸,并且后期扩展也比较麻烦,这时候就可以用到装置者模式。

    代码实现:

    1.豆浆属于饮品,创建一个饮品的接口,后期可能还会卖果汁之类的其他饮品

    package com.zkxtd.test;
    
    /**
     * 饮品
     * @Author zhouhe
     * @Date 2019/10/28 9:59
     */
    public interface Drink {
    
        //抽象组件
        //价格
        public double money();
        //描述
        public String desc();
    }

    2.创建被装饰者,豆浆,实现饮品Drink接口

    package com.zkxtd.test;
    
    /**
     * 豆浆
     * 豆浆属于饮品,所以要实现 Drink 这个接口
     * @Author zhouhe
     * @Date 2019/10/28 10:02
     */
    
    public class Soya implements Drink{
    
        //被装饰者
        @Override
        public double money() {
            return 5;
        }
    
        @Override
        public String desc() {
            return "纯豆浆";
        }
    }

    3.创建一个装饰器,它是一个抽象类,实现Drink,返回装饰后的结果

    package com.zkxtd.test;
    
    /**
     * 抽象类
     * @Author zhouhe
     * @Date 2019/10/28 10:08
     */
    public abstract class Decorator implements Drink{
    
        //装饰器
        //1.抽象类
        //2.实现抽象组件接口
        //3.持有抽象接口的引用
    
        //定义私有的饮品接口引用
        private Drink drink;
        public Decorator(Drink drink){
            this.drink = drink;
        }
    
        /**
         * 重写方法,返回装饰后的结果
         * @return
         */
        @Override
        public double money() {
            return drink.money();
        }
    
        @Override
        public String desc() {
            return drink.desc();
        }
    }

    4.具体装饰

      红豆

    package com.zkxtd.test;
    
    /**
     * 红豆
     * @Author zhouhe
     * @Date 2019/10/28 10:15
     */
    public class RedBean extends Decorator{
    
        /**
         * 在使用ReadBean 的时候需要把 drink 传给父类
         * @param drink
         */
        public RedBean(Drink drink) {
            super(drink);
        }
    
    
        /**
         * 重写价格
         * @return
         */
        @Override
        public double money() {
            return super.money()+3.2;
        }
    
        /**
         * 重写描述
         * @return
         */
        @Override
        public String desc() {
            return super.desc()+"+红豆";
        }
    }

      鸡蛋

    package com.zkxtd.test;
    
    /**
     * @Author zhouhe
     * @Date 2019/10/28 10:20
     */
    public class Egg extends Decorator {
    
        public Egg(Drink drink) {
            super(drink);
        }
    
        @Override
        public double money() {
            return super.money()+3.9;
        }
    
        @Override
        public String desc() {
            return super.desc()+"+鸡蛋";
        }
    }

      糖

    package com.zkxtd.test;
    
    /**
     * 糖
     * @Author zhouhe
     * @Date 2019/10/28 10:21
     */
    public class Sugar extends Decorator {
    
        public Sugar(Drink drink) {
            super(drink);
        }
    
        @Override
        public double money() {
            return super.money()+2.1;
        }
    
        @Override
        public String desc() {
            return super.desc()+"+糖";
        }
    }

    5.测试类

    package com.zkxtd.test;
    
    /**
     * @Author zhouhe
     * @Date 2019/10/28 10:24
     */
    public class Test {
    
        public static void main(String[] args) {
            //开始搭配
    
            //1.创建豆浆对象(豆浆属于饮品,我们返回一个饮品)
            Drink soya = new Soya();
            System.out.println(soya.money());   //打印纯豆浆的信息
            System.out.println(soya.desc());
    
            //2.往纯豆浆里面加红豆
            //把红豆加到豆浆里面,返回的还是饮品
            Drink redBeanSoya = new RedBean(soya);
            System.out.println(redBeanSoya.money());   //打印加红豆的豆浆的信息
            System.out.println(redBeanSoya.desc());
    
            //3.向红豆豆浆中加入鸡蛋
            //返回的还是饮品
            Drink erbs = new Egg(redBeanSoya);
            System.out.println(erbs.money());   //打印相关信息
            System.out.println(erbs.desc());
        }
    }

     使用装饰者模式之后,任何的一个具体装饰都可以装饰当前的一个饮品

    现在如果需要加入一种新的辅料西瓜,那么只要建一个西瓜类,然后进行搭配就可以了

    package com.zkxtd.test;
    
    /**
     * 西瓜
     * @Author zhouhe
     * @Date 2019/10/28 10:37
     */
    public class Xigua extends Decorator {
    
        public Xigua(Drink drink) {
            super(drink);
        }
    
        @Override
        public double money() {
            return super.money()+4.0;
        }
    
        @Override
        public String desc() {
            return super.desc()+"+西瓜";
        }
    }

    还可以装饰果汁,果汁也属于饮品

    package com.zkxtd.test;
    
    /**
     * 果汁
     * @Author zhouhe
     * @Date 2019/10/28 10:43
     */
    public class Fruit implements Drink{
        
        @Override
        public double money() {
            return 6;
        }
    
        @Override
        public String desc() {
            return "果汁";
        }
    }

      在测试类中开始搭配果汁

  • 相关阅读:
    Mybatis入门
    结合模板导出PDF文件
    生成Excel文件
    生成PDF文件
    BeanFactory not initialized or already closed
    Oracle数据库的视图
    ORACLE简介
    Cookie和session
    【cookie的使用】&【Session】
    过滤器的相关知识
  • 原文地址:https://www.cnblogs.com/zhouheblog/p/11750954.html
Copyright © 2011-2022 走看看