当前位置: 首页 > news >正文

设计模式之装饰模式(Decorator)

前言

        这个模式带给我们有关组合跟继承非常多的思考

定义

        “单一职责” 模式。动态(组合)的给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码 & 减少子类个数)
 

动机

        在某些情况下我们可能会 “过度的使用继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多)。各种子类的组合(扩展功能的组合)会导致更多子类的膨胀

        如何使 “对象功能的扩展” 能够根据需要来动态的实现?同时避免 “扩展功能的增多” 带来的子类膨胀问题? 从而使得任何 “功能扩展变化” 所导致的影响降为最低?

案例

      代码

// 版本1
//业务操作
class Stream{
public:virtual char Read(int number) = 0;virtual void Seek(int position) = 0;virtual void Write(char data) = 0;virtual ~Stream(){}
};//主体类
class FileStream : public Stream {
public:virtual char Read(int number) {//读文件流}virtual void Seek(int position) {//定位文件流}virtual void Write(char data) {//写文件流}};class NetworkStream : public Stream {
public:virtual char Read(int number) {//读网络流}virtual void Seek(int position) {//定位网络流}virtual void Write(char data) {//写网络流}
};class MemoryStream : public Stream {
public:virtual char Read(int number) {//读内存流}virtual void Seek(int position) {//定位内存流}virtual void Write(char data) {//写内存流}
};//扩展操作
class CryptoFileStream : public FileStream {
public:virtual char Read(int number) {//额外的加密操作...FileStream::Read(number);//读文件流}virtual void Seek(int position) { //额外的加密操作...FileStream::Seek(position);//定位文件流//额外的加密操作...}virtual void Write(byte data) {//额外的加密操作...FileStream::Write(data);//写文件流//额外的加密操作...}
};class CryptoNetworkStream : public NetworkStream{
public:virtual char Read(int number) {//额外的加密操作...NetworkStream::Read(number);//读网络流}virtual void Seek(int position) {//额外的加密操作...NetworkStream::Seek(position);//定位网络流//额外的加密操作...}virtual void Write(byte data) {//额外的加密操作...NetworkStream::Write(data);//写网络流//额外的加密操作...}
};class CryptoMemoryStream : public MemoryStream {
public:virtual char Read(int number) {//额外的加密操作...MemoryStream::Read(number);//读内存流}virtual void Seek(int position) {//额外的加密操作...MemoryStream::Seek(position);//定位内存流//额外的加密操作...}virtual void Write(byte data) {//额外的加密操作...MemoryStream::Write(data);//写内存流//额外的加密操作...}
};class BufferedFileStream : public FileStream {//...
};class BufferedNetworkStream : public NetworkStream {//...
};class BufferedMemoryStream : public MemoryStream {//...
}class CryptoBufferedFileStream : public FileStream {
public:virtual char Read(int number) {//额外的加密操作...//额外的缓冲操作...FileStream::Read(number);//读文件流}virtual void Seek(int position) {//额外的加密操作...//额外的缓冲操作...FileStream::Seek(position);//定位文件流//额外的加密操作...//额外的缓冲操作...}virtual void Write(byte data) {//额外的加密操作...//额外的缓冲操作...FileStream::Write(data);//写文件流//额外的加密操作...//额外的缓冲操作...}
};void Process() {//编译时装配CryptoFileStream *fs1 = new CryptoFileStream();BufferedFileStream *fs2 = new BufferedFileStream();CryptoBufferedFileStream *fs3 =new CryptoBufferedFileStream();
}// 版本2
//业务操作
class Stream{
public:virtual char Read(int number) = 0;virtual void Seek(int position) = 0;virtual void Write(char data) = 0;virtual ~Stream(){}
};//主体类
class FileStream : public Stream {
public:virtual char Read(int number) {//读文件流}virtual void Seek(int position) {//定位文件流}virtual void Write(char data) {//写文件流}};class NetworkStream : public Stream {
public:virtual char Read(int number) {//读网络流}virtual void Seek(int position) {//定位网络流}virtual void Write(char data) {//写网络流}
};class MemoryStream : public Stream {
public:virtual char Read(int number) {//读内存流}virtual void Seek(int position) {//定位内存流}virtual void Write(char data) {//写内存流}
};//扩展操作
class CryptoStream : public Stream {Stream* stream; //...public:CryptoStream(Stream* stm) : stream(stm) {}virtual char Read(int number) {//额外的加密操作...stream->Read(number);//读文件流}virtual void Seek(int position) {//额外的加密操作...stream::Seek(position);//定位文件流//额外的加密操作...}virtual void Write(byte data) {//额外的加密操作...stream::Write(data);//写文件流//额外的加密操作...}
};class BufferedStream : public Stream{Stream* stream; //...public:BufferedStream(Stream* stm):stream(stm) {}//...
};void Process() {//运行时装配FileStream* s1= new FileStream();CryptoStream* s2= new CryptoStream(s1);BufferedStream* s3= new BufferedStream(s1);BufferedStream* s4= new BufferedStream(s2);
}// 版本3
//业务操作
class Stream{
public:virtual char Read(int number) = 0;virtual void Seek(int position) = 0;virtual void Write(char data) = 0;virtual ~Stream(){}
};//主体类
class FileStream : public Stream {
public:virtual char Read(int number) {//读文件流}virtual void Seek(int position) {//定位文件流}virtual void Write(char data) {//写文件流}};class NetworkStream : public Stream {
public:virtual char Read(int number) {//读网络流}virtual void Seek(int position) {//定位网络流}virtual void Write(char data) {//写网络流}
};class MemoryStream : public Stream {
public:virtual char Read(int number) {//读内存流}virtual void Seek(int position) {//定位内存流}virtual void Write(char data) {//写内存流}
};//扩展操作
DecoratorStream : public Stream {
protected:Stream* stream; //...DecoratorStream(Stream * stm) : stream(stm) {}
};class CryptoStream : public DecoratorStream {
public:CryptoStream(Stream* stm):DecoratorStream(stm) {}virtual char Read(int number) {   //额外的加密操作...stream->Read(number); //读文件流}virtual void Seek(int position) {//额外的加密操作...stream::Seek(position); //定位文件流//额外的加密操作...}virtual void Write(byte data) {//额外的加密操作...stream::Write(data); //写文件流//额外的加密操作...}
};class BufferedStream : public DecoratorStream{Stream* stream; //...   
public:BufferedStream(Stream* stm):DecoratorStream(stm) {     }//...
};void Process(){//运行时装配FileStream* s1 = new FileStream();CryptoStream* s2 = new CryptoStream(s1);BufferedStream* s3 = new BufferedStream(s1); BufferedStream* s4 = new BufferedStream(s2);
}

          图

优化前
装饰模式

类图

        

总结

        通过采用组合而非继承的手法, Decorator模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了使用继承带来的 “灵活性差” 和 “多子类衍生问题”
        Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类
        Decorator模式的目的并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰”的含义

相关文章:

设计模式之装饰模式(Decorator)

前言 这个模式带给我们有关组合跟继承非常多的思考 定义 “单一职责” 模式。动态(组合)的给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码 & 减少…...

大数据-146 Apache Kudu 安装运行 Dockerfile 模拟集群 启动测试

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…...

React入门准备

React是什么 React是一个用于构建用户界面的JavaScript框架,用于构建“可预期的”和“声明式的”Web用户界面,特别适合于构建那些数据会随时间改变的大型应用的用户界面。 它起源于Facebook的内部项目,因为对市场上所有JavaScript MVC框架都…...

robomimic基础教程(四)——开源数据集

robomimic开源了大量数据集及仿真环境,数据集标准格式为HDF5 目录 一、基础要求 二、使用步骤 1. 下载数据集 2. 后处理 3. 训练 4. 查看训练结果 三、HDF5数据集结构与可视化 1. 数据集结构 (1)根级别(data 组 group&a…...

胤娲科技:AI界的超级充电宝——忆阻器如何让LLM告别电量焦虑

当AI遇上“记忆橡皮擦”,电量不再是问题! 嘿,朋友们,你们是否曾经因为手机电量不足而焦虑得像个无头苍蝇?想象一下,如果这种“电量焦虑”也蔓延到了AI界, 特别是那些聪明绝顶但“耗电如喝水”的…...

前端大模型入门:使用Transformers.js手搓纯网页版RAG(二)- qwen1.5-0.5B - 纯前端不调接口

书接上文,本文完了RAG的后半部分,在浏览器运行qwen1.5-0.5B实现了增强搜索全流程。但受限于浏览器和模型性能,仅适合于研究、离线和高隐私场景,但对前端小伙伴来说大模型也不是那么遥不可及了,附带全部代码&#xff0c…...

K-means聚类分析对比

K-means聚类分析,不同K值聚类对比,该内容是关于K-means聚类分析的,主要探讨了不同K值对聚类结果的影响。K-means聚类是一种常见的数据分析方法,用于将数据集划分为K个不同的类别。在这个过程中,选择合适的K值是非常关键…...

tar命令:压缩、解压的好工具

一、命令简介 用途: tar​ 命令用于创建归档文件(tarball),以及从归档文件中提取文件。 标签: 文件管理,归档。 特点: 归档文件可以保留原始文件和目录的层次结构,通常使用 .tar ​…...

Mac电脑上最简单安装Python的方式

背景 最近换了一台新的 MacBook Air 电脑,所有的开发软件都没有了,需要重新配环境,而我现在最常用的开发程序就是Python。这篇文章记录一下我新Mac电脑安装Python的全过程,也给大家一些思路上的提醒。 以下是我新电脑的配置&…...

Linux基础命令cd详解

cd(change directory)命令是 Linux 中用于更改当前工作目录的基础命令。它没有很多复杂的参数,但它的使用非常频繁。以下是 cd 命令的详细说明及示例。 基本语法 cd [选项] [路径] 常用选项 -L : 使用逻辑路径(默认选项&…...

【大模型对话 的界面搭建-Open WebUI】

Open WebUI 前身就是 Ollama WebUI,为 Ollama 提供一个可视化界面,可以完全离线运行,支持 Ollama 和兼容 OpenAI 的 API。 github网址 https://github.com/open-webui/open-webui安装 第一种 docker安装 如果ollama 安装在同一台服务器上&…...

如何在算家云搭建text-generation-webui(文本生成)

一、text-generation-webui 简介 text-generation-webui 是一个流行的用于文本生成的 Gradio Web UI。支持 transformers、GPTQ、AWQ、EXL2、llama.cpp (GGUF)、Llama 模型。 它的特点如下, 3 种界面模式:default (two columns), notebook, chat支持多…...

【Java SE】初遇Java,数据类型,运算符

🔥博客主页🔥:【 坊钰_CSDN博客 】 欢迎各位点赞👍评论✍收藏⭐ 1. Java 概述 1.1 Java 是什么 Java 是一种高级计算机语言,是一种可以编写跨平台应用软件,完全面向对象的程序设计语言。Java 语言简单易学…...

XSS(内含DVWA)

目录 一.XSS的攻击方式: 1. 反射型 XSS(Reflected XSS) 2. 存储型 XSS(Stored XSS) 3. DOM型 XSS(DOM-based XSS) 总结 二..XSS的危害 三.常见的XSS方式 1.script标签 四.常见基本过滤方…...

【SpringCloud】环境和工程搭建

环境和工程搭建 1. 案例介绍1.1 需求1.2 服务拆分服务拆分原则服务拆分⽰例 2. 项目搭建 1. 案例介绍 1.1 需求 实现⼀个电商平台(不真实实现, 仅为演⽰) ⼀个电商平台包含的内容⾮常多, 以京东为例, 仅从⾸⻚上就可以看到巨多的功能 我们该如何实现呢? 如果把这些功能全部…...

基于Java开发的(控制台)模拟的多用户多级目录的文件系统

多级文件系统 1 设计目的 为了加深对文件系统内部功能和实现过程的理解,设计一个模拟的多用户多级目录的文件系统,并实现具体的文件物理结构、目录结构以及较为完善的文件操作命令集。 2 设计内容 2.1系统操作 操作命令风格:本文件系统的…...

tailwindcss group-hover 不生效

无效 <li class"group"><div class"tw-opacity-0 group-hover:tw-opacity-100" /> </li>配了tw前缀&#xff0c;group要改成tw-group // tailwind.config.jsmodule.exports {prefix: "tw-", }<li class"tw-group&q…...

python环境配置问题(个人经验)

很久没配置 python 新环境了&#xff0c;最近新项目需要进行配置&#xff0c;在配置过程中发现了不少问题&#xff0c;记录下。 问题1&#xff1a;fatal error: longintrepr.h: 没有那个文件或目录 这个问题的原因是新环境的 python 版本(3.10以上)与本地的版本(3.8.x)差异过…...

BERT训练之数据集处理(代码实现)

目录 1读取文件数据 2.生成下一句预测任务的数据 3.预测下一个句子 4.生成遮蔽语言模型任务的数据 5.从词元中得到遮掩的数据 6.将文本转化为预训练数据集 7.封装函数类 8.调用 import os import random import torch import dltools 1读取文件数据 def _read_wiki(data_d…...

一款辅助渗透测试过程,让渗透测试报告一键生成

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…...

Magma智能剪辑系统:视频自动生成实战

Magma智能剪辑系统&#xff1a;视频自动生成实战 1. 引言 想象一下这样的场景&#xff1a;你有一个精彩的视频创意&#xff0c;写好了详细的脚本&#xff0c;但面对一堆零散的素材片段却无从下手。传统的视频剪辑需要逐帧挑选、拼接、添加转场&#xff0c;一个几分钟的视频可…...

小白也能学会:MogFace透明蒙版可视化,人脸检测不再难

小白也能学会&#xff1a;MogFace透明蒙版可视化&#xff0c;人脸检测不再难 1. 为什么需要透明蒙版可视化&#xff1f; 想象一下这样的场景&#xff1a;你拍了一张全家福&#xff0c;想用AI工具检测照片中有多少人。传统的检测工具会在每个人脸上画一个绿色的方框&#xff0…...

终极指南:Czkawka开源文件管理工具,5分钟解决存储空间不足难题

终极指南&#xff1a;Czkawka开源文件管理工具&#xff0c;5分钟解决存储空间不足难题 【免费下载链接】czkawka Multi functional app to find duplicates, empty folders, similar images etc. 项目地址: https://gitcode.com/GitHub_Trending/cz/czkawka 你是否经常遇…...

Z-Image-Turbo LoRA Web服务安全加固:禁用前端覆盖负面提示+后端content policy双层防护

Z-Image-Turbo LoRA Web服务安全加固&#xff1a;禁用前端覆盖负面提示后端content policy双层防护 1. 项目概述与安全挑战 造相-Z-Image-Turbo 亚洲美女LoRA Web服务是一个基于Z-Image-Turbo模型的图片生成平台&#xff0c;集成了laonansheng/Asian-beauty-Z-Image-Turbo-To…...

Phi-4-reasoning-vision-15B快速上手:使用Postman完成图像问答API全流程调试

Phi-4-reasoning-vision-15B快速上手&#xff1a;使用Postman完成图像问答API全流程调试 1. 引言&#xff1a;认识视觉推理模型 Phi-4-reasoning-vision-15B是微软推出的新一代视觉多模态推理模型&#xff0c;它能像人类一样理解图片内容并进行智能问答。想象一下&#xff0c…...

TEdit终极指南:如何用免费地图编辑器10倍提升泰拉瑞亚创作效率

TEdit终极指南&#xff1a;如何用免费地图编辑器10倍提升泰拉瑞亚创作效率 【免费下载链接】Terraria-Map-Editor TEdit - Terraria Map Editor - TEdit is a stand alone, open source map editor for Terraria. It lets you edit maps just like (almost) paint! It also let…...

Kodi PVR IPTV Simple全方位应用指南:从入门到精通的多场景解决方案

Kodi PVR IPTV Simple全方位应用指南&#xff1a;从入门到精通的多场景解决方案 【免费下载链接】pvr.iptvsimple IPTV Simple client for Kodi PVR 项目地址: https://gitcode.com/gh_mirrors/pv/pvr.iptvsimple 一、场景痛点分析&#xff1a;当IPTV体验不如预期时&…...

Heritrix3源码深度解析:从CrawlURI到ProcessorChain的执行流程

Heritrix3源码深度解析&#xff1a;从CrawlURI到ProcessorChain的执行流程 【免费下载链接】heritrix3 Heritrix is the Internet Archives open-source, extensible, web-scale, archival-quality web crawler project. 项目地址: https://gitcode.com/gh_mirrors/he/herit…...

noice.nvim终极性能优化指南:让你的Neovim编辑器运行如飞

noice.nvim终极性能优化指南&#xff1a;让你的Neovim编辑器运行如飞 【免费下载链接】noice.nvim &#x1f4a5; Highly experimental plugin that completely replaces the UI for messages, cmdline and the popupmenu. 项目地址: https://gitcode.com/gh_mirrors/no/noic…...

忍者绘卷Z-Image Turbo新手避坑:3个技巧搞定负向提示词

忍者绘卷Z-Image Turbo新手避坑&#xff1a;3个技巧搞定负向提示词 1. 负向提示词在忍者绘卷中的特殊价值 在忍者绘卷Z-Image Turbo这个专为二次元/火影忍者风格优化的AI绘画工具中&#xff0c;负向提示词扮演着"封印术"般的角色。它不仅仅是简单的排除列表&#x…...