12、【装饰器模式】动态地为对象添加新功能

news2024/11/15 10:06:06

你好,我是程序员雪球。

今天我们来聊聊 23 种设计模式中,一种常见的结构型模式,装饰器模式。聊聊它的设计思想、实现原理,应用场景,以及如何使用。

 47b4369cb75d47768a60a12970014c91.png

 

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许在不改变原始类的基础上,动态地为对象添加新的功能或行为。它通过创建一个包装类来包装原始类的实例,并在包装类中提供新的功能。这种模式的核心思想是“组合优于继承”,因为它允许在运行时动态地选择和组合不同的功能。

 

一、设计思想

装饰器模式的设计思想是将功能的添加与类的继承解耦。在传统的面向对象编程中,如果需要为一个类添加新的功能,通常会使用继承来扩展类的功能。然而,继承存在一些问题,例如代码冗余、类的层次结构复杂、灵活性较差等。装饰器模式通过创建一个包装类来包装原始类的实例,并在包装类中提供新的功能,从而避免了这些问题。

 

二、实现原理:

装饰器模式的实现原理是通过创建一个抽象装饰器类和具体装饰器类来实现的。抽象装饰器类定义了一个抽象方法,该方法接受一个原始类的实例作为参数,并返回一个包装类的实例。具体装饰器类实现了抽象装饰器类的抽象方法,并在包装类中提供了新的功能。

 

三、应用场景

装饰器模式适用于需要在不改变原始类的基础上,动态地为对象添加新的功能或行为的场景。例如:

 

1. 扩展性:如果你的系统需要不断地添加新的功能,而这些功能可能会影响到现有类的结构,那么使用装饰器模式可以避免修改现有类的代码,从而提高系统的扩展性。

2. 灵活性:如果你的系统需要根据不同的需求来动态地组合不同的功能,那么使用装饰器模式可以提供更大的灵活性。

3. 重用性:如果你的系统中有一些通用的功能,例如日志记录、性能监控等,那么使用装饰器模式可以将这些功能封装成装饰器类,从而提高代码的重用性。

4. 可维护性:如果你的系统中有一些复杂的功能,例如权限验证、数据加密等,那么使用装饰器模式可以将这些功能封装成装饰器类,从而提高系统的可维护性。

 

四、示例代码

 

下面是一个使用 Java 实现的装饰器模式的示例代码:

 

java 复制

public class DecoratorPatternExample {

    public static void main(String[] args) {

        // 创建原始对象

        Component component = new Component();

        // 创建装饰对象

        ComponentDecorator decorator1 = new ComponentDecorator1(component);

        ComponentDecorator decorator2 = new ComponentDecorator2(decorator1);

        // 调用方法

        decorator2.operation();

    }

}

 

// 原始类

abstract class Component {

    public abstract void operation();

}

 

// 具体原始类

class ComponentImpl extends Component {

    @Override

    public void operation() {

        System.out.println("Component operation()");

    }

}

 

// 抽象装饰器类

abstract class ComponentDecorator extends Component {

    protected Component component;

 

    public ComponentDecorator(Component component) {

        this.component = component;

    }

 

    @Override

    public void operation() {

        component.operation();

    }

}

 

// 具体装饰器类 1

class ComponentDecorator1 extends ComponentDecorator {

    public ComponentDecorator1(Component component) {

        super(component);

    }

 

    @Override

    public void operation() {

        super.operation();

        // 添加新的功能

        System.out.println("ComponentDecorator1 operation()");

    }

}

 

// 具体装饰器类 2

class ComponentDecorator2 extends ComponentDecorator {

    public ComponentDecorator2(Component component) {

        super(component);

    }

 

    @Override

    public void operation() {

        super.operation();

        // 添加新的功能

        System.out.println("ComponentDecorator2 operation()");

    }

}

 

 

在上述示例中,我们创建了一个原始类 Component 和两个具体的原始类 ComponentImpl ,以及一个抽象装饰器类 ComponentDecorator 和两个具体的装饰器类 ComponentDecorator1 和 ComponentDecorator2 。在 ComponentDecorator 类中,我们定义了一个 component 属性来保存原始类的实例,并在 operation 方法中调用原始类的 operation 方法。在具体的装饰器类中,我们可以在 operation 方法中添加新的功能,并在调用原始类的 operation 方法之前或之后执行。

 

在 main 方法中,我们创建了一个原始对象 component 和两个装饰对象 decorator1 和 decorator2 。我们将原始对象作为参数传递给装饰对象的构造函数,从而创建了一个装饰对象的链。最后,我们调用装饰对象的 operation 方法,从而实现了动态地添加新的功能。

 

装饰器模式的优点是可以在不改变原始类的基础上,动态地为对象添加新的功能或行为,从而提高系统的扩展性和灵活性。它的缺点是可能会导致类的层次结构复杂,并且可能会导致代码的可读性和可维护性降低。

 b743f8d6232f444fb976bbf4e9c2a9b0.png

 

总结

一、设计思想

装饰器模式的设计思想是将功能的添加与类的继承解耦。

二、实现原理

装饰器模式的实现原理是通过创建一个抽象装饰器类和具体装饰器类来实现的。

三、应用场景

装饰器模式适用于需要在不改变原始类的基础上,动态地为对象添加新的功能或行为的场景。例如:

1. 日志记录;

2. 性能监控;

3. 权限验证;

4. 数据加密;

 

讨论环节

为了方便你理解和巩固今天的内容,我给你留下两个讨论题,请在评论区与我一起讨论吧。

 

1. 装饰器模式的核心设计思想是什么?

2. 请说说你用过装饰器模式的场景?

 

如果觉得有收获,请双击支持,关注,后期我会持续更新更多相关知识。

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

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

相关文章

智慧水务是什么样的?如何打造智慧水务大屏?

在信息化和数字化快速发展的今天,智慧水务作为城市供水管理的重要组成部分,正变得越来越重要。智慧水务大屏作为智慧水务系统的可视化核心,不仅提升了水务管理的效率,而且通过数据的实时监控和分析,为决策者提供了强有…

揭秘爬虫技术:助你打开网络数据的大门

在当今信息爆炸的时代,网络上蕴藏着各种宝贵的数据资源,而要想获取这些宝藏,爬虫技术无疑是最为有效的利器之一。今天我将向大家深入探讨爬虫技术的奥秘,并带领大家一起走进这个数据世界的大门。 文章目录 什么是爬虫技术&#xf…

垃圾焚烧发电:从国资到专业公司,运营模式新变革|中联环保圈

近日,云南富源县生活垃圾焚烧发电项目运营管理技术服务招标引发广泛关注,与此同时,众多垃圾焚烧发电项目也纷纷启动了运管工作的招标。值得注意的是这些项目的招标人均为当地国资,且其中多数缺乏项目的运营经验。 在垃圾焚烧发电行…

4个在ArcGIS中可加载的图源分享

数据是GIS的血液。 这里分享4个来自网友分享的图源,该图源可以直接在ArcGIS中打开进行查看。 4个图源分享 你可以先打开ArcMap软件,然后将以下文分拖放到软件中打开即可查看。 4个图源 这4个图源分别为有地名和路网的地形地图、电子地图、有地名和路…

mysql-connector 交叉编译

1.下载 官网选择对应的系统以及版本,这里我用的是6.1.5https://downloads.mysql.com/archives/c-c/ 2.解压 tar -zxvf mysql-connector-c-6.1.5-src.tar.gz 3.先常规编译(因为交叉编译的过程中,会用到生成的二进制文件) cd m…

Llama3-8B+ LLaMA-Factory 中文微调

Llama3-8B LLaMA-Factory 中文微调 Llama3是目前开源大模型中最优秀的模型之一,但是原生的Llama3模型训练的中文语料占比非常低,因此在中文的表现方便略微欠佳! 本教程就以Llama3-8B-Instruct开源模型为模型基座,通过开源程序LL…

深度相机(3D相机)

传统的RGB彩色相机称为2D相机, 只能得到2D的图像信息, 无法得到物体与相机的距离信息,也就是深度信息。 顾名思义, 深度相机除了获取2D信息,还能得到深度信息,也叫RGBD相机, 或3D相机。 顺便提…

人像摄影姿势入门,人像拍照姿势详解

一、资料前言 本套人像摄影资料,大小537.44M,共有17个文件。 二、资料目录 《如何摆出好POSE》.黑面.影印版.pdf 《人像摄影姿势入门》.pdf 《人像摄影技巧》.pdf 《人像摄影摆姿指南》.比尔.赫特尔.扫描版.pdf 《人像摄影摆姿全集》龙文摄影.彩图…

三羟甲基氨基甲烷(TRIS)应用场景广泛 苏州亚科科技是主要供应商

三羟甲基氨基甲烷(TRIS)应用场景广泛 苏州亚科科技是主要供应商 三羟甲基氨基甲烷(TRIS)是一种有机化合物,外观为白色晶体,溶于水。三羟甲基氨基甲烷分子结构中含有一个氮原子和三个羟基,反应活…

C语言指针+-整数、指针-指针、指针关系运算、指针和数组、二级指针、指针数组

文章目录 前言一、指针 - 整数二、指针 - 指针三、指针的关系运算四、指针和数组五、二级指针六、指针数组指针数组可以将几个一维数组模拟成二维数组 总结 前言 C语言指针整数、指针-指针、指针关系运算、指针和数组、二级指针、指针数组等介绍,还包括指针数组将几…

UE4_常见动画节点学习_Two Bone IK双骨骼IK

学习资料,仅供参考! Two Bone IK 控制器将逆运动(IK)解算器应用于到如角色四肢等3关节链。 变量( HandIKWeight )被用于在角色的 hand_l 和 hand_r 控制器上驱动 关节目标位置(Joint Target Lo…

无锡日报:用超算系统设计国产民航飞机!“神威”,再显神威!

用国产超算系统 设计国产民用飞机 ✈ 我国推进高水平科技自立自强 又迈出坚实一步 4月19日,来自国内航空领域和计算机领域的专家相聚国家超级计算无锡中心,启动“面向新一代国产超算系统的民用飞机多学科联合设计优化技术与软件”项目,并…

线上剧本杀小程序开发,未来行业的发展趋势?

当下,剧本杀成为了大众最喜欢的娱乐方式之一,作为以沉浸式为主的剧本杀正成为新时代下的发展潮流。 数据显示,剧本杀行业已达到了百亿元。面对发展迅猛的剧本杀市场,越来越多的资本进入到了市场中,剧本杀的产业链也逐…

OpenHarmony实战开发-如何实现tabContent内容可以在tabBar上显示并且tabBar可以响应滑动事件的功能。

介绍 本示例实现了tabContent内容可以在tabBar上显示并且tabBar可以响应滑动事件的功能。 效果图预览 使用说明 1.点击播放按钮进行视频播放,按住进度条按钮和进度条下方区域可以拖动进度条,更改视频播放进度。 实现思路 原生的Tabs组件&#xff0c…

微服架构基础设施环境平台搭建 -(六)Kubesphere 部署Redis服务 设置访问Redis密码

微服架构基础设施环境平台搭建 -(六)Kubesphere 部署Redis服务 & 设置访问Redis密码 微服架构基础设施环境平台搭建 系列文章 微服架构基础设施环境平台搭建 -(一)基础环境准备 微服架构基础设施环境平台搭建 -(二…

记账本React案例(Redux管理状态)

文章目录 整体架构流程 环境搭建 创建项目 技术细节 一、别名路径配置 1.路径解析配置(webpack) ,将/解析为src/ 2.路径联想配置(vsCode),使用vscode编辑器时,自动联想出来src文件夹下的…

Day13.一刷数据结构算法(C语言版) 102二叉树的层序遍历;226翻转二叉树;101对称二叉树

一.102二叉树的层序遍历 二叉树的层序遍历力扣题目 1.思路分析 这道题我没有什么好的思路,而且力扣给的函数形式看得有点懵,所以我找到一个相对好理解的题解,具体可以参考下方链接。 力扣题解 说明: 返回值:可…

《从零开始的Java世界》10File类与IO流

《从零开始的Java世界》系列主要讲解Javase部分,从最简单的程序设计到面向对象编程,再到异常处理、常用API的使用,最后到注解、反射,涵盖Java基础所需的所有知识点。学习者应该从学会如何使用,到知道其实现原理全方位式…

【养生】个人参考:五脏运动

如有侵权可以下架,仅应用于个人查阅

BM25检索算法 python

1.简介 BM25(Best Matching 25)是一种经典的信息检索算法,是基于 TF-IDF算法的改进版本,旨在解决、TF-IDF算法的一些不足之处。其被广泛应用于信息检索领域的排名函数,用于估计文档D与用户查询Q之间的相关性。它是一种…