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

embedded/2024/10/21 0:20:49/

你好,我是程序员雪球。

今天我们来聊聊 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.ppmy.cn/embedded/19724.html

相关文章

AI:谷歌的colab免费训练模型,并且千兆网速,下载模型和库巨快,训练的速度普通,适合测试一些预训练的任务

下面是colab的官网,可以免费使用cpu和部分GPU, 千兆网速,下载模型和库巨快。 https://colab.research.google.com/drive 打开链接后的界面如下,相当于是jupyter notebook界面 点击左上角的logo或者直接访问下面链接 https://dr…

商城数据库(53-56)

53——订单商品表(wang_order-goods) CREATE TABLE wang_order_goods (id int(11) NOT NULL AUTO_INCREMENT COMMENT 自增ID,orderId int(11) NOT NULL COMMENT 订单ID,goodsId int(11) NOT NULL COMMENT 商品ID,goodsNum int(11) NOT NULL DEFAULT 0 C…

卷积神经网络

通义灵码 卷积神经网络(Convolutional Neural Networks, CNN)是一种专门设计用于处理具有网格结构数据(如图像、视频或序列数据)的深度学习模型。CNNs因其在计算机视觉任务(如图像分类、物体检测、语义分割等&#xf…

【深度学习】yolo-World,数据标注,zeroshot,目标检测

仓库:https://github.com/AILab-CVC/YOLO-World 下载权重: 仓库下载和环境设置 下载仓库:使用以下命令从 GitHub 上克隆仓库: git clone --recursive https://github.com/AILab-CVC/YOLO-World.git创建并激活环境&#xff1a…

强化训练:day5(游游的you、腐烂的苹果、孩子们的游戏(圆圈中最后剩下的数)

文章目录 前言1. 游游的you1.1 题目描述1.2 解题思路1.3 代码实现 2. 腐烂的苹果2.1 题目描述2.2 解题思路2.3 代码实现 3. 孩子们的游戏(圆圈中最后剩下的数)3.1 题目描述3.2 解题思路3.3 代码实现 总结 前言 本章内容:游游的you、腐烂的苹果、孩子们的游戏(圆圈中…

富格林:可信操作提升做单盈利

富格林指出,黄金市场有涨有跌,有赚有赔,投资黄金并非有机会天天盈利,能够盈利出金最重要的原因还是投资者有正规精妙的技术。在黄金交易中,投资者一定要掌握可信的交易方法,提前布局好策略,这样…

ReactJS中使用TypeScript

TypeScript TypeScript 实际上就是具有强类型的 JavaScript,可以对类型进行强校验,好处是代码阅读起来比较清晰,代码类型出现问题时,在编译时就可以发现,而不会在运行时由于类型的错误而导致报错。但是,从…

从零开始:UniApp 项目搭建指南

正文: 在移动应用开发领域,UniApp 作为一款基于 Vue.js 的跨平台框架,为开发者提供了更加便捷的方式来构建同时支持多个平台的应用程序。本文将带领你从零开始,一步步地搭建一个 UniApp 项目,并介绍其中的关键步骤和注…