23种设计模式(六)——装饰模式【单一职责】

news2024/11/24 6:37:01

文章目录

    • 意图
    • 什么时候使用装饰
        • 真实世界类比
    • 装饰模式的实现
    • 装饰模式的优缺点

亦称: 装饰者模式、装饰器模式、Wrapper、Decorator

意图

装饰者模式(Decorator Pattern)允许向一个现有的对象扩展新的功能,同时不改变其结构。主要解决直接继承下因功能的不断横向扩展导致子类膨胀的问题,无需考虑子类的维护。

在这里插入图片描述

什么时候使用装饰

1、需要大量的子类为某一个对象进行职责增强的时候,可以使用装饰器模式

2、希望使用继承对于类进行动态扩展的时候,可以考虑使用装饰器模式

真实世界类比

在这里插入图片描述

穿上多件衣服将获得组合性的效果。

穿衣服是使用装饰的一个例子。 觉得冷时, 你可以穿一件毛衣。 如果穿毛衣还觉得冷, 你可以再套上一件夹克。 如果遇到下雨, 你还可以再穿一件雨衣。 所有这些衣物都 “扩展” 了你的基本行为, 但它们并不是你的一部分, 如果你不再需要某件衣物, 可以方便地随时脱掉。

装饰模式的实现

1、确保业务逻辑可用一个基本组件及多个额外可选层次表示。

2、找出基本组件和可选层次的通用方法。 创建一个组件接口并在其中声明这些方法。

3、创建一个具体组件类, 并定义其基础行为。

4、创建装饰基类, 使用一个成员变量存储指向被封装对象的引用。 该成员变量必须被声明为组件接口类型, 从而能在运行时连接具体组件和装饰。 装饰基类必须将所有工作委派给被封装的对象。

5、确保所有类实现组件接口。

6、将装饰基类扩展为具体装饰。 具体装饰必须在调用父类方法 (总是委派给被封装对象) 之前或之后执行自身的行为。

7、客户端代码负责创建装饰并将其组合成客户端所需的形式。

class Component {
public:
	virtual ~Component() {}
	virtual std::string Operation() const = 0;
};
/**
 * Concrete Components provide default implementations of the operations. There
 * might be several variations of these classes.
 */
class ConcreteComponent : public Component {
public:
	std::string Operation() const override {
		return "ConcreteComponent";
	}
};
/**
 * The base Decorator class follows the same interface as the other components.
 * The primary purpose of this class is to define the wrapping interface for all
 * concrete decorators. The default implementation of the wrapping code might
 * include a field for storing a wrapped component and the means to initialize
 * it.
 */
class Decorator : public Component {
	/**
	 * @var Component
	 */
protected:
	Component* component_;

public:
	Decorator(Component* component) : component_(component) {
	}
	/**
	 * The Decorator delegates all work to the wrapped component.
	 */
	std::string Operation() const override {
		return this->component_->Operation();
	}
};
/**
 * Concrete Decorators call the wrapped object and alter its result in some way.
 */
class ConcreteDecoratorA : public Decorator {
	/**
	 * Decorators may call parent implementation of the operation, instead of
	 * calling the wrapped object directly. This approach simplifies extension of
	 * decorator classes.
	 */
public:
	ConcreteDecoratorA(Component* component) : Decorator(component) {
	}
	std::string Operation() const override {
		return "ConcreteDecoratorA(" + Decorator::Operation() + ")";
	}
};
/**
 * Decorators can execute their behavior either before or after the call to a
 * wrapped object.
 */
class ConcreteDecoratorB : public Decorator {
public:
	ConcreteDecoratorB(Component* component) : Decorator(component) {
	}

	std::string Operation() const override {
		return "ConcreteDecoratorB(" + Decorator::Operation() + ")";
	}
};

装饰模式的优缺点

优点缺点
无需创建新子类即可扩展对象的行为在封装器栈中删除特定封装器比较困难
可以在运行时添加或删除对象的功能实现行为不受装饰栈顺序影响的装饰比较困难
可以用多个装饰封装对象来组合几种行为各层的初始化配置代码看上去可能会很糟糕
单一职责原则。 可以将实现了许多不同行为的一个大类拆分为多个较小的类

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

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

相关文章

Allegro如何快速找到差分不耦合处操作指导

Allegro如何快速找到差分不耦合处操作指导 做PCB设计的时候,需要检查差分对不耦合的地方,让差分不耦合的地方高亮出来 具体操作如下 用Allegro172版本打开pcb,选择View选择Vision Manager

抖快社交,变道求生

配图来自Canva可画 抖音、快手再一次杀回了社交市场。 2022年12月底,快手App store版本更新,在原有的快手热榜、朋友动态、快手拍摄的基础上,新增亲密贴贴、快手直播等新锁屏组件,通过强化产品的交互功能,增强用户的…

针对游戏开发CG制作的搬砖人员的资源搜索技巧分享—【持续补充篇】

一.常用搜索技巧分享 1.视频参考类(bilibili,youtube,常用的视频官网,其实可以满足了,再不行就在百度/Google搜一下) 2.教程和代码类 github Bootstrap Well magebox realtimevfx

Python项目(Django框架)天天生鲜在CentOS7.9搭建运行

CentOS安装python3 为方便管理,在CentOS桌面创建一个文件夹,将软件包下载到这里,右键--在终端打开 安装python3.9.7 : wget https://www.python.org/ftp/python/3.9.7/Python-3.9.7.tgz (命令前的sudo如果是root用户可以去掉&…

深度学习目标检测基础_sigmoid和softmax函数

文章目录sigmoid和softmaxsigmoid函数softmax函数总结sigmoid和softmax sigmoid和softmax都是分类函数,他们的区别如下 sigmoid函数 Sigmoid 多标签分类问题多个正确答案非独占输出(例如胸部X光检查、住院)。构建分类器,解决有…

威纶通触摸屏配方功能的使用方法示例

威纶通触摸屏配方功能的使用方法示例 本次和大家分享通过触摸屏内部指针+偏移地址+控制元件实现配方功能的具体方法, 另外以前给大家分享过利用宏指令实现配方功能的方法,具体可参考以下链接中的内容: 威纶通触摸屏的配方功能具体使用方法介绍(宏指令写入PLC) 如下图所示…

Dubbo 服务引用

Dubbo 服务引用 0. 概述 Dubbo 服务引用的时机有两个,第一个是在 Spring 容器调用 ReferenceBean 的 afterPropertiesSet 方法时引用服务,第二个是在 ReferenceBean 对应的服务被注入到其他类中时引用。这两个引用服务的时机区别在于,第一个…

锅圈的新消费“第三条路”走得通吗?

文|螳螂观察 作者|kinki 临近春节,线下餐饮行业在经历了三年的寒冬之后,相信会在今年迎来一个“暖春”。不过,年夜饭一直存在“一桌难求”的现象,结合疫情因素,相信今年仍有不少消费会选择在家用餐。 因此&#xff…

生成随机用户名的测试数据

大家好,才是真的好。 记得我们以前讲过一篇《自动批量生成Notes应用测试数据!》,利用Java自动生成大批量的测试数据,今天我们介绍使用LotusScript代码来实现自动生成随机数据,主要是随机的用户名。 我们的方法很简单…

〖百宝书-思维锻炼②〗——知识是人类的供需和营养品

大家好,我是涵子,今天我们来聊聊知识。 💬 人生格言:Stay foolish, stay kind.💬 📫 如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀 &#x…

Feed 流系统

差不多十年前,随着功能机的淘汰和智能机的普及,互联网开始进入移动互联网时代,最具代表性的产品就是微博、微信,以及后来的今日头条、快手等。这些移动互联网时代的新产品在过去几年间借着智能手机的风高速成长。 这些产品都是Fee…

VueJs中的shallowRef与shallowReactive的使用比较

01shallowRef()函数如果传入基本数据类型,那么shallowRef与ref的作用基本没有什么区别,也就是浅层的ref的内部值将会原样的存储和暴露,并不会被深层递归地转为响应式但如果是对象的话,那么就存在区别了的,shallowRef不处理对象类型的数据其实,它就是只处理基本数据类型的响应式…

从 JMM 透析 volatile 与 synchronized 原理

在面试、并发编程、一些开源框架中总是会遇到 volatile 与 synchronized 。synchronized 如何保证并发安全?volatile 语义的内存可见性指的是什么?这其中又跟 JMM 有什么关系,在并发编程中 JMM 的作用是什么,为什么需要 JMM&#…

信用评分分卡简介introduction of credit score card

背景 随着金融科技初创企业的兴起,过去 5 年中出现了许多新的消费信贷机构,与传统银行展开竞争。他们通常瞄准银行认为规模太小或因金融危机期间发生的后期损失而不得不削减贷款的细分市场。通俗的讲就是消费金融公司瞄准了银行的次贷市场。 这些新的消…

修改Pom文件需要注意的问题

1.从远程nuxaus拉不回来个别包该如何解决 进入仓库目录下,把该包的目录删除了,重新拉 rm -r 包目录 如果还是不行,可能是idea内存不够,尝试关闭暂时不用但是已经打开的项目,减少内存使用,删除包目录重试…

肌电信号采集电路分析

最近在开发肌电信号的采集,表面肌电信号是非常微弱的生物信号,正常人体表面肌电信号赋值为0--1.5mV,主要能量频段集中在10--150Hz。电路主要是根据原始信号,设计相应的放大电路、滤波电路,下面直接放原理图说明。一级放…

生物素点击试剂1255942-07-4,DBCO-PEG4-Biotin,生物素-PEG4-二苯基环辛炔

中英文别名:CAS号:1255942-07-4| 英文名:DBCO-PEG4-Biotin |中文名:二苯基环辛炔-PEG4-生物素,二苯基环辛炔-四聚乙 二醇-生物素物理参数:CASNumber:1255942-07-4Molecular formula:…

2023的网安玩家,会和布洛芬退烧一样“凉”得快吗?

2021年,《数据安全法》《网络安全产业高质量发展三年行动计划》《个人信息保护法》《网络产品安全漏洞管理规定》等政策法规扎堆发布,二级市场网安公司市值一度起飞,网络安全行业如日中天,业内大佬纷纷感慨总算熬出了头&#xff0…

python-MySQL数据库基础(一)数据库基础知识、MYSQL的介绍和安装、数据类型

数据库介绍 数据库(database)简称DB,实际上是一个文件集合,是一个存储数据的仓库,本质上是一个文件系统,数据库是按照特定的格式把数据存储起来,用户可以对存储的数据进行增删改查等操作,音乐,…

读书笔记:手写数字识别 ← 斋藤康毅

求解机器学习问题的步骤可以分为“学习”和“推理”两个阶段。本例假设“学习”阶段已经完成,并将学习到的权重和偏置参数保存在pickle文件sample_weight.pkl中。至于是如何学习的,斋藤康毅指出会在后续章节详述。之后,使用学习到的权重和偏置…