• 13【装饰器设计模式】



    十三、装饰器设计模式

    13.1 装饰器设计模式简介

    13.1.1 装饰器设计模式概述

    装饰器设计模式(Decorator Pattern):也叫包装器设计模式(Wrapper Pattern),指在不改变原有对象的基础上,动态地给对象添加一些额外的功能。就增加功能来说,装饰器模式相比生成子类更为灵活。

    装饰设计模式的核心就是功能的扩展(增强),装饰器模式提供了比继承更有弹性的替代方案;

    13.1.2 装饰器设计模式的角色

    装饰设计模式有如下角色:

    • 1)抽象组件(Component):被装饰类的顶层父类,其定义了被装饰对象的行为;
    • 2)具体组件(ConcreteComponent):Component的具体实现,被装饰对象;
    • 3)抽象装饰器(Decorator):装饰器的顶层父类,其内部拥有一个被装饰对象,使用被装饰对象(ConcreteComponent)来保证其原有功能;
    • 4)具体装饰器(ConcreteDecorator):Decorator的具体实现,封装具体扩展的功能;

    13.2 装饰器设计模式的实现

    13.2.1 案例

    【对学生进行装饰(增强)】

    一个普通的Java学生只会JavaSE、Servlet、JSP等技术,通过W3C网站装饰后的学生掌握了Spring、MyBaits、SpringMVC等技术,通过菜鸟教程网站装饰后掌握了Spring、Hibernate、Struts2等技术;

    UML类图如下:

    在这里插入图片描述

    • 抽象组件:
    package com.pattern.demo;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 抽象学生(抽象构建)
     */
    public abstract class Student {
        protected abstract void knowledge();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 具体组件:
    package com.pattern.demo;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 普通Java学生(具体构建)
     */
    public class JavaStudent extends Student {
        @Override
        protected void knowledge() {
            System.out.println("JavaSE");
            System.out.println("Servlet");
            System.out.println("JSP");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 抽象装饰器:
    package com.pattern.demo;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 抽象学生装饰器(抽象装饰器)
     */
    public abstract class StudentDecorator extends Student  {
    
        protected Student student;
    
        public StudentDecorator(Student student){
            this.student=student;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 具体装饰器:
    package com.pattern.demo;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 具体装饰器
     */
    public class W3cSchoolStudentDecorator extends StudentDecorator {
    
        public W3cSchoolStudentDecorator(Student student) {
            super(student);
        }
    
        @Override
        protected void knowledge() {
            // 学生原有功能
            student.knowledge();
            System.out.println("MyBatis");
            System.out.println("Spring");
            System.out.println("SpringMVC");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 具体装饰器:
    package com.pattern.demo;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 具体装饰器
     */
    public class CaiNiaoStudentDecorator extends StudentDecorator {
        public CaiNiaoStudentDecorator(Student student) {
            super(student);
        }
    
        @Override
        protected void knowledge() {
            // 保留原有的功能
            student.knowledge();
    
            System.out.println("Spring");
            System.out.println("Hibernate");
            System.out.println("Struts2");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 测试代码:
    package com.pattern.demo;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro:
     */
    public class Demo01 {
        public static void main(String[] args) {
    
            // 没有装饰的Java学生
            System.out.println("没有装饰的Java学生: ");
            Student javaStudent=new JavaStudent();
            javaStudent.knowledge();
            System.out.println("-------------------");
    
            // 经过W3c加强的学生
            System.out.println("经过W3c加强的学生: ");
            StudentDecorator w3cSchoolStudentDecorator=new W3cSchoolStudentDecorator(javaStudent);
            w3cSchoolStudentDecorator.knowledge();
            System.out.println("-------------------");
    
            // 经过菜鸟教程加强的学生
            System.out.println("经过菜鸟教程加强的学生: ");
            StudentDecorator caiNiaoStudentDecorator=new CaiNiaoStudentDecorator(javaStudent);
            caiNiaoStudentDecorator.knowledge();
            System.out.println("-------------------");
    
            System.out.println("经过W3c和菜鸟教程加强的学生: ");
            new CaiNiaoStudentDecorator(new W3cSchoolStudentDecorator(new JavaStudent())).knowledge();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    13.2.2 装饰与代理的区别

    从代理模式和装饰器模式的实现代码上来看,两者几乎一模一样。但其实两者有着本质的不同;

    使用装饰器设计模式强调的是自身功能的扩展。即什么事情都自己干,自己不会就去学习,装饰器本身也是一个抽象组件的子类,装饰器(Decorator)就是增强具体组件(ConcreteComponent)的功能上的封装;

    代理设计模式强调的增强后的结果,即只在乎结果,不在乎过程,自己不干增强的事情,自己不会做就找其他人(代理对象)做;然后最终达到目标效果即可;

    13.3 装饰器设计模式的优缺点

    • 优点:
      • 1)使用装饰器对类继续扩展比继承灵活,在不改变原有对象的情况下可以对一个对象进行增强;
      • 2)通过使用不同的装饰器来组合,可以实现更加强大的效果
      • 3)装饰器设计模式完全遵守开闭原则,想要扩展什么功能就新建装饰器来装饰组件
    • 缺点:
      • 1)会造成系统出现更多的类
      • 2)在装饰嵌套时会有一定的复杂性
  • 相关阅读:
    强大博客搭建全过程(1)-hexo博客搭建保姆级教程
    根据前序遍历结果构造二叉搜索树
    Bootstrap-- 栅格系统
    css中实现背景方格
    在元宇宙产业生态链中,8K技术扮演了何种角色?
    【信息安全】浅谈三种XSS(跨站脚本攻击)的攻击流程与防御措施
    定时器如何计算触发频率?
    Vue3中如何通过内嵌iframe传递参数与接收参数
    3i平台体验性能加持,13600KF+B760M+撼与科技A770 TITAN装机体验
    自己实现 SpringMVC 底层机制 系列之-实现任务阶段 7- 完成简单视图解析
  • 原文地址:https://blog.csdn.net/Bb15070047748/article/details/126368714