详解设计模式:装饰器模式

news2025/1/13 13:35:23

装饰器模式(Decorator Pattern)也称为包装模式(Wrapper Pattern),是 GoF 的 23 种设计模式中的一种结构型设计模式。装饰器模式 是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能)。

装饰器模式 的核心是功能扩展,使用装饰器模式可以透明且动态地扩展类的功能

本篇内容包括:关于装饰器模式、装饰器实现 Demo


文章目录

    • 一、关于装饰器模式
        • 1、关于装饰器模式
        • 2、关于装饰器模式的构成
        • 3、关于装饰器模式的UML
        • 4、关于装饰器模式的优缺点
        • 5、装饰器模式、代理模式之间的区别
    • 二、装饰器实现 Demo
        • 1、Demo 实现
        • 2、Demo 测试


一、关于装饰器模式

1、关于装饰器模式

装饰器模式(Decorator Pattern)也称为包装模式(Wrapper Pattern),是 GoF 的 23 种设计模式中的一种结构型设计模式。

装饰器模式 是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能)。

装饰器模式 的核心是功能扩展,使用装饰器模式可以透明且动态地扩展类的功能

2、关于装饰器模式的构成

适配器模式一般包含四种角色:

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

3、关于装饰器模式的UML

装饰器模式

4、关于装饰器模式的优缺点

# 装饰器模式的优点

  • 功能扩展灵活,而不依赖继承;
  • 可以对同一个对象进行多种装饰;

# 装饰器模式的缺点

装饰方式可能比较复杂,如果嵌套太多,容易造成代码可读性变差和出错。

5、装饰器模式、代理模式之间的区别

对装饰器模式来说,装饰者(decorator)和被装饰者(decoratee)都实现同一个接口。对代理模式来说,代理类(proxy class)和真实处理的类(real class)都实现同一个接口,他们之间的边界确实比较模糊,两者都是对类的方法进行扩展,具体区别如下:

  1. 装饰器模式强调的是增强自身,在被装饰之后你能够在被增强的类上使用增强后的功能。增强后你还是你,只不过能力更强了而已;代理模式强调要让别人帮你去做一些本身与你业务没有太多关系的职责(记录日志、设置缓存)。代理模式是为了实现对象的控制,因为被代理的对象往往难以直接获得或者是其内部不想暴露出来。
  2. 装饰模式是以对客户端透明的方式扩展对象的功能,是继承方案的一个替代方案;代理模式则是给一个对象提供一个代理对象,并由代理对象来控制对原有对象的引用;

二、装饰器实现 Demo

1、Demo 实现

# Component 抽象构件角色

interface Component {
    public void operation();
}

# ConcreteComponent 具体构件角色

class ConcreteComponent implements Component {
    public ConcreteComponent() {
        System.out.println("创建具体构件角色");
    }
 
    public void operation() {
        System.out.println("调用具体构件角色的方法operation()");
    }
}

# Decorator 抽象装饰角色

abstract class Decorator implements Component {
    private Component component;
 
    public Decorator(Component component) {
        this.component = component;
    }
 
    public void operation() {
        component.operation();
    }
}

# ConcreteDecorator 具体装饰角色

class ConcreteDecorator extends Decorator {
  
    public ConcreteDecorator(Component component) {
        super(component);
    }
 
    public void operation() {
        super.operation();
        addedFunction();
    }
 
    public void addedFunction() {
        System.out.println("为具体构件角色增加额外的功能addedFunction()");
    }
}

2、Demo 测试

public class Client {
    public static void main(String[] args) {
        Component p = new ConcreteComponent();
        p.operation();
       
        Component d = new ConcreteDecorator(p);
        d.operation();
    }
}

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

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

相关文章

3.7.2、IP地址(网际层)

我们日常的大多数网络应用中,属于数据链路层的 MAC 地址,和属于网络层的 IP 地址都在使用,它们之间存在一定的关系。这里主要介绍 IP 地址的作用 1、基本介绍 IP 地址是因特网(Internet)上的主机和路由器所使用的地址,用于标识两…

osgEarth示例分析——osgearth_graticule

前言 本示例最具有借鉴的功能:绘制网格、网格上的文字显示、拾取地球的坐标。在地球网格示例中,可以设置4种网格。执行命令如下: // --geodetic osgearth_graticuled.exe --geodetic earth_image\china-simple.earth // --utm osgearth_gr…

[附源码]Python计算机毕业设计Django大学生心理测评系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,我…

磁盘划分和磁盘格式化

文章目录列出装置的 UUID 等参数parted 列出磁盘的分区表类型与分区信息磁盘分区:gdisk、fdisk用 gdisk 新增分区槽用 gdisk 删除一个分区槽磁盘格式化(建立文件系统)XFS 文件系统 mkfs.xfsXFS 文件系统 for RAID 效能优化(Option…

【Linux】环境变量

文章目录一.什么是环境变量二.常见的环境变量1.常见的环境变量和与之相关的命令2.PATH指定命令搜索路径3.env显示所有环境变量4.echo查看环境变量三.本地变量与环境变量的联系四.获取环境变量的三种方式1.getenv()函数获取环境变量2.利用命令行参数3.利用第三方变量一.什么是环…

如何校准Linux服务器时间

最近服务器上的时间与北京时间出现偏差,而Java代码里java.util.Date获取的是服务器时间,导致当前时间错误。 Linux查看服务器当前时间 查看当前时区:date -R 查看当前日期和时间:date 校准Linux服务器时间 Linux中有个ntp包可…

【Unity】URP渲染管线下代码获取相机的Volume Mask属性

步骤1. 引用URP的命名空间2. 获取摄像机3.通过URP扩展获取Volume Mask属性附 层级的相关代码Reference1. 引用URP的命名空间 using UnityEngine.Rendering.Universal;2. 获取摄像机 这里可以使用公有拖拽或者私有赋值的方式。 如果使用拖拽,则: publi…

神经网络和深度学习-多分类问题Softmax Classifier

多分类问题Softmax Classifier 在之前做糖尿病数据集的时候做的二分类问题,因为只有两类,所以只需要输出一个概率值,另一个概率值用1去减去就可以得到 实际上在大多数数据集中是在处理一个多分类问题,例如MNIST中有10类标签 神经…

Hifiasm-meta | 你没看错!基于宏基因组的完成图!!

哈佛大学医学院Dana-Farber癌症研究所李恒课题组重磅推出三代HiFi宏基因组组装软件——hifiasm-meta。研究论文“Metagenome assembly of high-fidelity long reads with hifiasm-meta”预印本在线发布。 宏基因组样本的do novo组装是研究微生物群落的常用方法。与单个物种的组…

RNA-seq 详细教程:分析准备(3)

学习目标 了解 RNA-seq 和差异表达基因的分析流程了解如何设计实验了解如何使用 R 语言进行数据分析1. 简介 在过去的十年中,RNA-seq 已成为转录组差异表达基因和 mRNA 可变剪切分析不可或缺的技术。正确识别哪些基因或转录本在特定条件下的表达情况,是理…

【FreeRTOS(四)】显示任务详细信息

文章目录显示任务详细信息 vTaskList代码示例显示任务详细信息 vTaskList 通过 vTaskList来协助分析操作系统当前 task 状态,以帮助优化内存,帮助定位栈溢出问题。 void vTaskList( char *pcWriteBuffer );parameterdescriptionpcWriteBuffer保存任务状态…

11.21~11.28日学习总结

首先这一周,主要进行的几个事情。 1.在星期一~星期二图书报账的相关事情处理已经完毕,记录了现在图书报账的相关流程,比以前的流程有不少改变,已经写了word记录了流程,给下一任图书管理员做参考。 2.进行了项目的中期…

mysql集群的主从复制搭建

1.master上和slave分别安装好mysql(5.7) 2.按照下面的方式进行安装 3.安装完成后,进行初始化,并找到默认的密码进行登录 4.设置为开机自,并检查状态 5.进行登录,用root账户,密码为生成的那个密码…

C++:STL之Vector实现

vector各函数 #include<iostream> #include<vector> using namespace std;namespace lz {//模拟实现vectortemplate<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;//默认成员函数vector(); …

SpringBoot项目如何引入外部jar及将外部jar打包到项目发布jar包

1、创建一个SpringBoot项目 下载项目之后将项目导入IDEA 2、如何添加外部jar包 准备一个外部的jar包&#xff0c; 我这里使用的是guava-31.1-jre.jar作为演示 下载地址&#xff1a;https://repo1.maven.org/maven2/com/google/guava/guava/31.1-jre/guava-31.1-jre.jar 在项…

黎曼的几何基础,维度

黎曼的几何基础&#xff0c;让数学领先物理100年&#xff0c;维度是人类最大的障碍 - 知乎 高斯很早就有了“高维几何”的想法&#xff0c;他曾经向他的同事们说起假想完全生活在二维表面上的“书虫”&#xff0c;并想要把这推广到高维空间的几何学中去。然而&#xff0c;由于害…

Java安全编码规范之Web安全漏洞

Java安全编码规范之Web安全漏洞安全现状漏洞案例事件一事件二事件三安全编码规范之常见的安全漏洞敏感数据编码概述漏洞危害常见关键字举例解决方案代码硬编码秘钥错误示例日志打印导致的敏感信息泄露漏洞概述关键字举例解决方案代码中在日志打印token 错误示例文件上传漏洞概述…

CSDN客诉周报第12期|修复10个重大bug,解决29个次要bug,采纳1个用户建议

听用户心声&#xff0c;解用户之需。hello&#xff0c;大家好&#xff0c;这里是《CSDN客诉周报》第12期&#xff0c;接下来就请大家一同回顾我们最近几周解决的bug&#xff5e; 一、重大问题 1、【博客】主页无法访问 反馈量&#xff1a;80 发生时间&#xff1a;10月30日下…

外汇天眼:Axi收回在RGT Capital的全部控制权,Eurotrader获得FCA牌照

在过去的一周里&#xff0c;国外外汇市场上有哪些值得关注的新闻&#xff0c;跟着天眼君一起了解下吧~具体新闻如下&#xff1a; 1、Axi收回在RGT Capital的全部控制权 据天眼君了解&#xff0c;总部位于澳大利亚的零售外汇和差价合约经纪商Axi在澳大利亚投资公司RGT Capital的…

AutoDL使用手册

官网&#xff1a;AutoDL-品质GPU租用平台-租GPU就上AutoDL 1.服务器购买 2.新建虚拟环境 conda create -n tf python3.8 # 构建一个虚拟环境&#xff0c;名为&#xff1a;tf conda init bash && source /root/.bashrc # 更新bashrc中的环境变量 conda acti…