zoukankan      html  css  js  c++  java
  • java设计模式-装饰器模式

    1.装饰器(Decorator)模式的定义

    • 指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

    2.装饰器模式的主要优缺点

    优点:

    • 采用装饰模式扩展对象的功能比采用继承方式更加灵活。
    • 可以设计出多个不同的具体装饰类,创造出多个不同行为的组合。

    缺点:

    • 装饰模式增加了许多子类,如果过度使用会使程序变得很复杂。

    3. 装饰器模式的主要角色

    • 抽象组件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
    • 具体组件(Concrete    Component)角色:实现抽象构件,通过装饰角色为其添加一些职责。
    • 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
    • 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

    从类图上看,装饰器模式与代理模式很像,是它们的目的不同,所以使用方法和适用场景上也就不同 ,装饰器模式与代理模式的区别:

    • 代理模式专注于对被代理对象的访问。
    • 装饰器模式专注于对被装饰对象附加额外功能。

    4.装饰器的结构图

     5.装饰器的实现,以coffee为例

    •  创建抽象组件类
    package com.lw.designpattern.decorate;
    
    /**
     * @Classname Coffee
     * @Description 抽象组件类,咖啡
     * @Author lw
     * @Date 2020-01-13 09:01
     */
    public interface Coffee {
    
        /**
         * 价格
         *
         * @return double
         */
        double price();
    
        /**
         * 配料
         *
         * @return String
         */
        String ingredients();
    }
    • 创建具体组件类
    package com.lw.designpattern.decorate;
    
    /**
     * @Classname SimpleCoffee
     * @Description 具体组件类,原味coffee
     * @Author lw
     * @Date 2020-01-13 09:02
     */
    public class SimpleCoffee implements Coffee {
    
        @Override
        public double price() {
            return 1;
        }
    
        @Override
        public String ingredients() {
            return "coffee";
        }
    }
    • 创建抽象装饰类
    package com.lw.designpattern.decorate;
    
    /**
     * @Classname AbstractCoffeeDecorator
     * @Description 抽象装饰类,咖啡的"装饰器"
     * @Author lw
     * @Date 2020-01-13 09:04
     */
    public abstract class AbstractCoffeeDecorator implements Coffee {
    
        protected Coffee coffee;
    
        public AbstractCoffeeDecorator(Coffee coffee) {
            this.coffee = coffee;
        }
    
        /**
         * 价格
         *
         * @return double
         */
        @Override
        public double price() {
            return coffee.price();
        }
    
        /**
         * 配料
         *
         * @return String
         */
        @Override
        public String ingredients() {
            return coffee.ingredients();
        }
    }
    • 创建具体装饰类,牛奶
    package com.lw.designpattern.decorate;
    
    /**
     * @Classname WithMilk
     * @Description 具体装饰类,牛奶
     * @Author lw
     * @Date 2020-01-13 09:10
     */
    public class WithMilk extends AbstractCoffeeDecorator {
    
        public WithMilk(Coffee house) {
            super(house);
        }
    
        /**
         * 价格
         *
         * @return double
         */
        @Override
        public double price() {
            double addPrice = 1;
            return super.price() + addPrice;
        }
    
        /**
         * 配料
         *
         * @return String
         */
        @Override
        public String ingredients() {
            String addIngredients = "milk";
            return super.ingredients() + "," + addIngredients;
        }
    }
    • 再创建一个具体装饰类,糖
    package com.lw.designpattern.decorate;
    
    /**
     * @Classname WithSugar
     * @Description 具体装饰类,糖
     * @Author lw
     * @Date 2020-01-13 09:10
     */
    public class WithSugar extends AbstractCoffeeDecorator {
    
        public WithSugar(Coffee house) {
            super(house);
        }
    
        /**
         * 价格
         *
         * @return double
         */
        @Override
        public double price() {
            double addPrice = 0.5;
            return super.price() + addPrice;
        }
    
        /**
         * 配料
         *
         * @return String
         */
        @Override
        public String ingredients() {
            String addIngredients = "sugar";
            return super.ingredients() + ","  + addIngredients;
        }
    }
    • 单元测试
      /**
         * 装饰者模式
         */
        @Test
        public void testDecorate() {
            // 原味咖啡
            Coffee c = new SimpleCoffee();
            System.out.println("花费了: " + c.price());
            System.out.println("配料: " + c.ingredients());
            System.out.println("============");
    
            // 增加牛奶的咖啡
            c = new WithMilk(c);
            System.out.println("花费了: " + c.price());
            System.out.println("配料: " + c.ingredients());
            System.out.println("============");
    
            // 增加糖的咖啡
            c = new WithSugar(c);
            System.out.println("花费了: " + c.price());
            System.out.println("配料: " + c.ingredients());
            System.out.println("============");
        }

    打印结果

     6.装饰器的适用场景

    • 运行时,你需要动态地为对象增加额外职责时。
    • 当你需要一个能够代替子类的类,借助它提供额外方法时。

    7.装饰器的扩展

    • Java提供的工具包中,IO相关工具就普遍大量使用了装饰器模式,例如充当装饰功能的IO类如BufferedInputStream等,又被称为高级流,通常将基本流作为高级流构造器的参数传入,将其作为高级流的一个关联对象,从而对其功能进行扩展和装饰。
    • 用BufferedInputStream和用FileInputStream去read一个文件实际使用方式上是一样的,能用FileInputStream.read(),就能用BufferedInputStream.read(),只不过,BufferedInputStream把FileInputStream包装了一下,增加了一个缓存,并不控制底层FileInputStream的read()行为。
  • 相关阅读:
    【HTML5 绘图与动画】使用canvas
    【H5新增元素和文档结构】新的全局属性 1. contentEditable 可编辑内容 2. contextmenu 快捷菜单 3. data 自定义属性 4. draggable 可拖动 5. dropzone 拖动数据 6. hidden 隐藏 7. spellcheck 语法检查 8. translate 可翻译
    【H5新增元素和文档结构】完善旧元素 1. a 超链接 2. ol 有序列表 3. dl 定义列表 4. cite 引用文本 5. small 小号字体 6. iframe 浮动框架 7. script 脚本
    【H5新增元素和文档结构】新的语义信息 1. address 2. time 3. figure 跟 figcaption 4. details 和 summary 5. mark 6. progress 7. meter 8. dialog 9.bdi 10. wbr 11. ruby、rt、rp 12. command
    【H5新增元素跟文档结构】新的文档结构 1. article 文章块 2. section 区块 3. nav 导航条 4. aside 辅助栏 5. main 主要区域 6. header 标题栏 7. hgroup 标题组 8. footer 页脚栏
    5_PHP数组_3_数组处理函数及其应用_9_数组集合运算函数
    【华为云技术分享】鲲鹏弹性云服务器GCC交叉编译环境搭建指南
    【华为云技术分享】7 分钟全面了解位运算
    【华为云技术分享】Linux内核编程环境 (1)
    【华为云技术分享】华为云MySQL 8.0正式商用,全新增强版开源利器强势来袭
  • 原文地址:https://www.cnblogs.com/lwcode6/p/12185620.html
Copyright © 2011-2022 走看看