Java特性之设计模式【装饰器模式】

news2024/11/15 8:43:10

一、装饰器模式

概述

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装

装饰器模式通过将对象包装在装饰器类中,以便动态地修改其行为

主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀

何时使用:在不想增加很多子类的情况下扩展类

优缺点

优点:

  • 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能

缺点:

  • 多层装饰比较复杂

1. 各个角色介绍

1.1 抽象组件(Component)

  • 定义了组合中所有对象的通用接口,可以是抽象类或接口。它声明了用于访问和管理子组件的方法,包括添加、删除、获取子组件等

1.2 具体组件(Concrete Component)

  • 是被装饰的原始对象,它定义了需要添加新功能的对象

1.3 抽象装饰器(Decorator)

  • 继承自抽象组件,它包含了一个抽象组件对象,并定义了与抽象组件相同的接口,同时可以通过组合方式持有其他装饰器对象

1.4 具体装饰器(Concrete Decorator)

  • 实现了抽象装饰器的接口,负责向抽象组件添加新的功能。具体装饰器通常会在调用原始对象的方法之前或之后执行自己的操作

2. UML图

​ 将创建一个 Shape 接口和实现了 Shape 接口的实体类。然后创建一个实现了 Shape 接口的抽象装饰类 ShapeDecorator,并把 Shape 对象作为它的实例变量。RedShapeDecorator 是实现了 ShapeDecorator 的实体类

在这里插入图片描述

3. 具体例子和代码

角色分配

  • Shape:形状接口

    • Rectangle:实现形状接口的长方形类
    • Circle:实现形状接口的圆形类
  • ShapeDecorator:形状装饰器抽象类

    • RedShapeDecorator:红色形状装饰器(继承ShapeDecorator)

3.1 抽象组件及其实现类

  • Shape
package com.vinjcent.prototype.decorator;

/**
 * @author vinjcent
 * @description 形状接口
 * @since 2024/3/15 16:23
 */
public interface Shape {

    /**
     * 形状绘制动作
     */
    void draw();

}

  • Rectangle
package com.vinjcent.prototype.decorator;

/**
 * @author vinjcent
 * @description 长方形
 * @since 2024/3/15 16:26
 */
public class Rectangle implements Shape {

    @Override
    public void draw() {
        System.out.println("Shape: Rectangle");
    }

}

  • Circle
package com.vinjcent.prototype.decorator;

/**
 * @author vinjcent
 * @description 圆形
 * @since 2024/3/15 16:28
 */
public class Circle implements Shape {

    @Override
    public void draw() {
        System.out.println("Shape: Circle");
    }

}

3.2 抽象装饰器及其具体装饰器

  • ShapeDecorator
package com.vinjcent.prototype.decorator;

/**
 * @author vinjcent
 * @description 形状装饰器
 * @since 2024/3/15 16:30
 */
public abstract class ShapeDecorator implements Shape {

    protected Shape decoratedShape;

    public ShapeDecorator(Shape decoratedShape) {
        this.decoratedShape = decoratedShape;
    }

    public void draw() {
        decoratedShape.draw();
    }

}

  • RedShapeDecorator
package com.vinjcent.prototype.decorator;

/**
 * @author vinjcent
 * @description 红色形状装饰器
 * @since 2024/3/15 16:32
 */
public class RedShapeDecorator extends ShapeDecorator {

    public RedShapeDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    @Override
    public void draw() {
        decoratedShape.draw();
        setRedBorder(decoratedShape);
    }

    private void setRedBorder(Shape decoratedShape) {
        System.out.println("Border Color: Red");
    }

}

3.3 测试主函数

package com.vinjcent.prototype.decorator;

/**
 * @author vinjcent
 * @description 装饰器模式
 * @since 2024/3/15 16:39
 */
public class Main {

    public static void main(String[] args) {

        Shape circle = new Circle();
        // ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
        // ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
        Shape redCircle = new RedShapeDecorator(new Circle());
        Shape redRectangle = new RedShapeDecorator(new Rectangle());
        System.out.println("Circle with normal border");
        circle.draw();

        System.out.println("\nCircle of red border");
        redCircle.draw();

        System.out.println("\nRectangle of red border");
        redRectangle.draw();
    }

}

  • 测试结果

在这里插入图片描述

4. 使用场景

  • 动态增强功能:使用装饰器模式可在运行时为对象灵活地增加额外功能。通过组合各种装饰器,能够实现不同功能的组合,而无需改变原始对象的代码
  • 避免继承的功能扩展:当使用继承来增强对象功能时会导致类的层次结构过于复杂时,考虑采用装饰器模式。通过组合而非继承来实现功能扩展,避免了深层次和复杂的类继承结构
  • 维护对象的封装性:若需为对象添加功能,同时又不愿修改原始对象的代码或破坏其封装性,可采用装饰器模式。该模式不改变原对象结构,只是在其上方增添功能
  • 弹性组合多项功能:若需为对象添加多项功能,且这些功能可弹性组合,则可采用装饰器模式。透过组合各种装饰器,能够实现各种功能的组合,而无需创建大量子类
  • 贯彻单一职责原则:在需要将功能添加与原始对象实现分离,以符合单一职责原则时,可采用装饰器模式。每个装饰器类专注于一个特定功能,这有助于使类的职责更加明确

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1534510.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据泄露问题怎么解决?迅软DSE加密软件助您守护重要信息

企业信息泄露的危害 企业数据泄露事件不仅给企业带来了经济损失和声誉损害,还可能导致用户个人信息的泄露,引起社会广泛关注。 因此,企业需要采取更加严格的数据保护措施,使用数据加密系统以防范潜在的数据泄露风险。同时&#…

Vue.js前端开发零基础教学(三)

目录 2.6 计算属性 2.7侦听器 2.8 样式绑定 2.8.1 绑定class属性 2.8.2 绑定style属性 2.9 阶段案例——学习计划表 2.6 计算属性 概念:Vue提供了计算属性来描述依赖响应式数据的复杂逻辑。 计算属性可以实时监听数据的变化,返回一个计算…

Premiere模板|200个视频标题文字动画pr字幕模板包

Premiere模板,13个类别200个Pr视频标题字幕文字动画模板mogrt包。 几乎适用于任何场景。粗体标题,标注,未来主义和线条标题,下三分之一,霓虹灯,带数字的标题,倒计时,表格&#xff0c…

智慧商显安卓主板MT8788_联发科MTK平台多媒体广告一体机方案

MT8788高性能智能主板,支持Android 9.0操作系统,支持双屏异显功能;MT8788是基于12nm工艺制程四核A73四核A53架构的八核心CPU,主频高达2.0GHz,拥有超强的通用计算性能。 MT8788主板采用10层二阶超高密度PCB板,集成了4G、百兆以太网、2.4G/5G 双频WiFi、蓝…

C# xaml框架以及Java的ORM介绍

c#有ASP.Net,.NET以及EF Core这几个重要的运行时和框架.分别用于web,应用以及数据库的ORM. 目前跨平台的有Avalonia UI,.Net MAUI以及Uno Platform,至于WPF等本身不是跨平台的,但可以依靠其他库实现跨平台.这里面Avalonia应该是认为bug比较少的. 当然目前最火的跨平台解决方案…

Python使用指定端口进行http请求的例子

使用requests库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class SourcePortAdapter(HTTPAdapter): """"Transport adapter" that allows us to set the source port.""" def __init__(self, port, *args, **kwargs): self.poolm…

Spring Cloud Alibaba微服务从入门到进阶(七)(服务容错-Sentinel)

雪崩效应 我们把基础服务故障,导致上层服务故障,并且这个故障不断放大的过程,成为雪崩效应。 雪崩效应,往往是因为服务没有做好容错造成的。 微服务常见容错方案 仓壁模式 比如让controller有自己独立的线程池,线程池满…

数据结构的概念大合集06(树和二叉树)

概念大合集06 1、树1.1 树的相关定义1.2 树的基本运算1.3 树的基本术语1.3.1 结点的度,树的度1.3.2 分支结点,叶子节点1.3.3 路径,路径长度1.3.4 孩子结点,双亲结点,兄弟结点1.3.5 结点层次,树的高度1.3.6 …

24.两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不会以 0 …

DELL交换机清空配置S4128T

备份配置 show run | no-more show inventory | no-more show environment | no-more show system brief | no-more -------------- 清除数据 delete startup-config system "sudo -i" //输入密码 rm -rf /config/etc/opt/dell/os10/db_init/startup.xml rm…

基于SpringBoot和Vue的大学生租房系统的设计与实现

今天要和大家聊的是一款今天要和大家聊的是一款基于SpringBoot和Vue的大学生租房系统的设计与实现。 !!! 有需要的小伙伴可以通过文章末尾名片咨询我哦!!! 💕💕作者:李同…

【Java11下载、安装、部署指南】

oracle jdk11下载 oracle jdk所有版本归档【archive】下载地址: https://www.oracle.com/java/technologies/downloads/archive/ oracle jdk11下载地址: https://www.oracle.com/java/technologies/javase/jdk11-archive-downloads.html 配置或修改wi…

【Python + Django】启动简单的文本页面

前言: 为了应付(bushi)毕业论文,总要自己亲手搞一个像模像样的项目出来吧 ~ ~ 希望自己能在新的连载中学到项目搭建的知识,这也算是为自己的测试经历增添光彩吧!!! 希望、希望大家…

MySQL 字段定义时的属性设置

开发的时候第一步就是建表,在创建表的时候,我们需要定义表的字段,每个字段都有一些属性,比如说是否为空,是否允许有默认值,是不是逐渐等。 这些约束字段的属性,可以让字段的值更符合我们的预期&…

③【Docker】Docker部署Nginx

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ ③【Docker】Docker部署Nginx docker拉取nginx…

【计算机网络篇】物理层(3)编码与调制

文章目录 🍔编码与调试⭐基本概念 🍔基本的带通调制方法和混合调制方法⭐基本的带通调制方法⭐混合调制方法 🍔编码与调试 物理层是OSI模型中的第一层,它负责在物理媒体上传输原始比特流。在物理层的编码和调试中,我们…

基于springboot的学生心理健康评估系统

技术:springbootvuemysql 一、系统背景 这次开发的学生心理咨询评估系统有管理员和用户。管理员可以管理个人中心,用户管理,试题管理,试卷管理,考试管理等。用户参加考试。经过前面自己查阅的网络知识,加上…

数据挖掘之关联规则

“啤酒和尿布的荣誉” 概念 项 item:单个的事物个体 ,I{i1,i2…im}是所有项的集合,|I|m是项的总数项集(item set)/模式(pattern):项的集合,包含k个项的项集称为k-项集数据集(data set)/数据库…

2024年最新分享提升Macbook运行速度的十大小技巧

经常听到小伙伴在抱怨PC电脑很慢,但是其实Mac电脑随着用的时间增长,运行速度也会越来越慢,那么造成Mac运行慢的原因有很多,可能是操作系统过时未更新,也可能是内存(RAM)不足,以下小编…

计算机二级C语言的注意事项及相应真题-6-程序设计

目录 51.将a所指数组主对角线上的元素分别乘以2;次对角线上的元素分别乘以3,依次放入指针p所指的数组中。计算过程中不得修改a所指数组中的数据52.将a、b中的两个两位正整数合并形成一个新的整数放在c中。合并的方式是:将a中的十位和个位数依次放在变量c的十位和千位…