13【装饰器设计模式】

本文介绍了装饰器设计模式,它允许在不修改原有对象的情况下动态添加功能。通过一个Java学生学习技术的例子,展示了如何使用装饰器模式为学生添加额外的技术知识,如W3C和菜鸟教程的学习内容。装饰器模式与代理模式的区别在于前者注重自身功能扩展,后者关注增强后的结果。该模式的优点包括灵活性和遵循开闭原则,但可能会导致更多的类和复杂性。
摘要由CSDN通过智能技术生成


十三、装饰器设计模式

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();
}
  • 具体组件:
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");
    }
}
  • 抽象装饰器:
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;
    }
}
  • 具体装饰器:
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");
    }
}
  • 具体装饰器:
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");
    }
}
  • 测试代码:
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();
    }
}

13.2.2 装饰与代理的区别

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

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

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

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

  • 优点:
    • 1)使用装饰器对类继续扩展比继承灵活,在不改变原有对象的情况下可以对一个对象进行增强;
    • 2)通过使用不同的装饰器来组合,可以实现更加强大的效果
    • 3)装饰器设计模式完全遵守开闭原则,想要扩展什么功能就新建装饰器来装饰组件
  • 缺点:
    • 1)会造成系统出现更多的类
    • 2)在装饰嵌套时会有一定的复杂性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

緑水長流*z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值