设计模式10——装饰模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。

装饰模式

是一种行为型模式。

目录

一、概述

1.1、主要的角色:

1.2、直观的理解装饰模式要干什么:

1.3、那么该如何思考呢?

1.4、我先给出描述对象之间关系的UML图:

1.5、什么是断点?

二、举例代码实现

2.1、对象之间的关系用UML图表示如下:

2.2、代码如下(建议你在本地试一下,加深印象):


一、概述

1、需要把所需的功能按正确的顺序串联起来进行控制;
2、动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活;
3、装饰模式是为已有的功能动态的添加更多功能的一种方式;
4、主要是给一个核心类 动态的添加各种功能。

1.1、主要的角色:

主要的角色分两种,但从代码(或技术)实现的角度看(为了充分使用面向对象语言的3大特性封装、继承、多态,还另外需要抽象类或接口)可能有4个:

  1. 组件类:组件类的抽象类或接口 + 组件类的实现类
  2. 装饰类:装饰类的抽象类或接口装饰类的实现类

1.2、直观的理解装饰模式要干什么:

举个简单例子,之前是只运行对象A,现在新加了对象B和对象C,当我们希望要运行的对象应该由对象A到对象B再到对象C,也就是希望对象运行之间有严格的顺序要求时,就可以尝试使用装饰模式。如我们希望达到的效果是这样的:

1.3、那么该如何思考呢?

可以从上可以看到,原先只有对象A,而对象B和对象C是后来加上的,且有严格的执行顺序,那么应用装饰模式后,我们可以认为:

  • 对象A为组件类
  • 对象B和对象C为装饰类,用来装饰对象A

除此之外,对于代码实现而言非常重要的东西是:

  • 装饰类里的“断点”(这个词是我拍脑子想的,是为了帮助我们理解如何实现此模式而产生的,下面我会解释它是什么)。

1.4、我先给出描述对象之间关系的UML图:

1.5、什么是断点?

这是我从代码实现的角度提出的,所以要从代码的角度解释:

就拿上面的简单的举例来说,我们可以很明确地看到执行顺序是A-》B-》C,但实际代码实现上并非这样有前后顺序,而是你中有我、我中有你,解释图如下:

看懂上图我们就理解断点的意义了,同时也能发现装饰模式远比我们想象的更加灵活,不只是简单的A-》B-》C,就不再举例了。

需要说明的是,不同语言具体的实现方式略有不同,如:python的语法本身就支持装饰器,使用起来也更容易;而Java则需要创建装饰器父类,然后具体的装饰对象要继承父类,将调用父类的方法当做断点使用。但他们的共同点就是都有一个断点,这个断点可以用来插入别的类或对象的代码去运行。

二、举例代码实现

现有一个组件类和装饰类A、装饰类B,我们希望可以先运行组件类、再运行装饰类A、再运行装饰类B。

不再分析了,例子本身比较简单,而且上面概述当中也说的很清楚了。就直接给uml图和Java实现代码:

2.1、对象之间的关系用UML图表示如下:

2.2、代码如下(建议你在本地试一下,加深印象):

Java实现。

组件类的抽象类:

abstract class Component {
    public abstract void operation();
}

具体的组件类:

public class ConcreteComponent extends Component {
    @Override
    public void operation() {
        System.out.println("具体组件对象的实际操作");
    }
}

装饰类的抽象类:

abstract class Decorator extends Component {
    protected Component component;

    public void setComponent(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        if (this.component != null) {
            component.operation();
        }
    }
}

装饰类A:

public class ConcreteDecoratorA extends Decorator {
    private String testA;

    @Override
    public void operation() {
        super.operation(); //断点
        this.testA = "具体装饰对象A的独有操作";
        System.out.println(this.testA);
    }
}

装饰类B:

public class ConcreteDecoratorB extends Decorator {
    @Override
    public void operation() {
        super.operation(); //断点
        this.testB();
    }

    private void testB() {
        System.out.println("具体装饰对象B的独有操作");
    }
}

主程序(发起请求的类):

public class Main {
    public static void main(String[] args) {
        ConcreteComponent component = new ConcreteComponent();
        ConcreteDecoratorA concreteDecoratorA = new ConcreteDecoratorA();
        ConcreteDecoratorB concreteDecoratorB = new ConcreteDecoratorB();
        concreteDecoratorA.setComponent(component);
        concreteDecoratorB.setComponent(concreteDecoratorA);
        concreteDecoratorB.operation();
    }
}

这里就不再举例了,可以把上面的Java例子复制到你本地,运行main函数试一下加深理解。这些代码都是我自己学习的时候根据一些教材手敲的,不存在bug可以直接运行。

如果觉得本文还不错,就请点个赞给作者一点鼓励吧!如果有建议,也请评论指教和讨论!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

笔记88:LeetCode_134_加油站

前言: 前言1:这个题的题目条件给的不太严谨,题目描述中说“如果存在解,则保证它是唯一的”,通过我的实践,我发现这句话的意思其实是本题的所有样例只有两种情况,无解/有唯一解;而不可…

【Spring】认识 Spring AOP

认识 Spring AOP 1.什么是 AOP2.AOP 中的概念3.用 AOP 方式管理日志3.1 编写 AOP 日志注解类3.2 编写控制器用于测试 1.什么是 AOP AOP(Aspect Oriented Program,面向切面编程)把业务功能分为核心、非核心两部分。 核心业务功能&#xff1a…

tcpdump源码分析

进入tcpdump.c(函数入口)之前,先看一些头文件netdissect.h里定义了一个数据结构struct netdissect_options来描述tcdpump支持的所有参数动作,每一个参数有对应的flag, 在tcpdump 的main 里面, 会根据用户的传入的参数来…

构建高效的在线培训机构CRM应用架构实践

在当今数字化时代,在线培训已成为教育行业的重要趋势之一。为了提供更好的学习体验和管理服务,在线培训机构需要构建高效的CRM(Customer Relationship Management)应用架构。本文将探讨在线培训机构CRM应用架构的设计与实践。 一、…

力扣周赛398题解

特殊数组Ⅰ 如果数组的每一对相邻元素都是两个奇偶性不同的数字,则该数组被认为是一个 特殊数组 。 Aging 有一个整数数组 nums。如果 nums 是一个 特殊数组 ,返回 true,否则返回 false。 示例 1: 输入:nums [1] …

数据结构和算法|排序算法系列(二)|冒泡排序

首先需要你对排序算法的评价维度和一个理想排序算法应该是什么样的有一个基本的认知: 《Hello算法之排序算法》 主要内容来自:Hello算法11.3 冒泡排序 我觉得冒泡排序非常有意思,也非常简单,就是不停地交换相邻的元素即可&#…

代码随想录算法训练营第四天| 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点 、 面试题 02.07. 链表相交、142.环形链表II

24. 两两交换链表中的节点 题目链接: 24. 两两交换链表中的节点 文档讲解:代码随想录 状态:没做出来,没有正确更新头节点,因为head和cur共享引用,会随着cur的移动,丢失之前存放的节点 错误代码&…

腾讯发布ELLA:为扩散模型注入LLM能力,提升复杂场景的图像生成,准确率超90%

前言 近年来,基于扩散模型的文本到图像生成技术取得了显著进步,能够生成高质量、逼真的图像。然而,大多数扩散模型仍然使用CLIP作为文本编码器,这限制了它们理解复杂提示的能力,例如包含多个物体、详细属性、复杂关系…

摄像头应用测试

作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生在读,研究方向无线联邦学习 擅长领域:驱动开发,嵌入式软件开发,BSP开发 作者主页:一个平凡而乐于分享的小比特的个人主页…

MySQL(一) 库和表的基础操作

1. 数据库基础 1.1 什么是数据库 存储数据用文件就可以了,为什么还要弄个数据库? 文件保存数据有以下几个缺点: 文件的安全性问题文件不利于数据查询和管理文件不利于存储海量数据文件在程序中控制不方便 数据库存储介质:磁盘内存 为了解…

学 C/C++ 具体能干什么?

学习 C 和 C 后,你可以从事许多不同的工作和项目,这两种语言以其高性能和低级控制而闻名,特别适合以下几个领域: 1. 系统编程 C 和 C 是系统编程的首选语言,适用于操作系统、驱动程序和嵌入式系统开发。 操作系统开发…

PgMP:项目集管理,哪些人适合学习?

美国项目管理协会(PMI)对项目集经理(Program Manager)的角色做出如下的定义: 在最少的领导/监督下,项目集经理PgMP负责在商业和组织目的下协调管理多个相关项目。这些项目含有跨部门、组织、地理区域…

【kubernetes】探索k8s集群中金丝雀发布后续 + 声明式资源管理yaml

目录 一、K8S常见的发布方式 1.1蓝绿发布 1.2灰度发布(金丝雀发布) 1.3滚动发布 二、金丝雀发布 三、声明式管理方法 3.1YAML 语法格式 3.1.1查看 api 资源版本标签 3.1.2查看资源简写 3.2YAML文件详解 3.2.1Deployment.yaml 3.2.2Pod.yaml …

国际版Tiktok抖音运营流量实战班:账号定位/作品发布/热门推送/等等-13节

课程目录 1-tiktok账号定位 1.mp4 2-tiktok作品发布技巧 1.mp4 3-tiktok数据功能如何开通 1.mp4 4-tiktok热门视频推送机制 1.mp4 5-如何发现热门视频 1.mp4 6-如何发现热门音乐 1.mp4 7-如何寻找热门标签 1.mp4 8-如何寻找垂直热门视频 1.mp4 9-如何发现热门挑战赛 1…

【C语言回顾】编译和链接

前言1. 编译2. 链接结语 上期回顾: 【C语言回顾】文件操作 个人主页:C_GUIQU 归属专栏:【C语言学习】 前言 各位小伙伴大家好!上期小编给大家讲解了C语言中的文件操作,接下来我们讲解一下编译和链接! 1. 编译 预处理…

C++11 线程库

C11 线程库 一.thread类1.介绍1.框架2.构造3.赋值4.join与joinable5.id和get_id6.this_thread命名空间7.yield8.演示 二.锁类1.互斥锁1.介绍2.使用1.配合lambda来使用2.ref 2.递归锁和时间锁1.递归锁介绍2.例子3.时间锁介绍 三.RAII管理锁类1.lock_guard1.介绍2.使用3.好处与不…

AOP总结

AOP是什么 AOP是面向切面编程,其目的是将横切关注点从核心业务代码中分离出来,通过动态代理等方式,实现代码的增强和解耦,使得其具有更好的可维护性和可扩展性。 其中横切关注点是多个类或对象的公共行为,如事务管理…

五种独立成分分析(ICA)

代码原理及流程 代码实现了混合信号的独立成分分析(ICA)过程,主要包括以下几个步骤: 原始语音信号读取与显示:首先读入原始的两个语音信号(music.wav和man.wav),并显示在图中的第一和第二个子图中。混合声…

mfc140.dll丢失原因和mfc140.dll丢失修复办法分享

mfc140.dll是与微软基础类库(Microsoft Foundation Classes, MFC)紧密相关的动态链接库(DLL)文件。MFC是微软为C开发者设计的一个应用程序框架,用于简化Windows应用程序的开发工作。以下是mfc140.dll文件的一些关键属性…

项目管理:敏捷实践框架

一、初识敏捷 什么是敏捷(Agile)?敏捷是思维方式。 传统开发模型 央企,国企50%-60%需求分析。整体是由文档控制的过程管理。 传统软件开发面临的问题: 交付周期长:3-6个月甚至更长沟通效果差:文档化沟通不及时按时发布低:技术债增多无法发版团队士气弱:死亡行军不关注…