C# 设计模式:装饰器模式与代理模式的区别

C# 设计模式:装饰器模式与代理模式的区别

在软件设计中,装饰器模式(Decorator Pattern)和代理模式(Proxy Pattern)都是结构型设计模式,它们的目的都是通过对对象进行包装,来增加或改变对象的行为。虽然它们有一些相似之处,但实际上,它们的设计初衷和使用场景有所不同。本文将通过对比这两种模式,帮助大家更好地理解它们的区别和应用场景。

1. 装饰器模式与代理模式的相似性

装饰器模式和代理模式在表面上有一定的相似性,主要体现在以下几个方面:

  • 都涉及到对对象的包装:无论是装饰器模式还是代理模式,都通过一个包装类来代理或装饰原有对象。
  • 都可以增强对象的功能:通过包装,装饰器模式和代理模式都可以在不改变原有对象代码的情况下,添加新的功能或行为。

然而,它们的核心差异在于目的和实现方式。

2. 装饰器模式 (Decorator Pattern)

目的:装饰器模式的目的是动态地为一个对象添加额外的功能或行为。装饰器通常是为了增强对象的功能,不会改变对象本身的行为。

特点

  • 装饰器模式的关键是递归地装饰对象。它通常是一个实现了相同接口或继承了相同类的对象,可以在运行时增加或修改被装饰对象的行为。
  • 装饰器模式可以在不修改原始对象的情况下,给对象动态地添加功能。

应用场景

  • 需要为一个对象添加额外的职责和行为,而又不想改变对象的结构。
  • 适合用在“责任链”或“动态行为扩展”场景中。
示例:C# 装饰器模式
using System;// 定义接口
public interface ICar
{void Assemble();
}// 具体组件:普通汽车
public class BasicCar : ICar
{public void Assemble(){Console.WriteLine("Assembling a basic car.");}
}// 装饰器:高级汽车
public class SportsCar : ICar
{private ICar car;public SportsCar(ICar car){this.car = car;}public void Assemble(){car.Assemble();Console.WriteLine("Adding features of sports car.");}
}// 装饰器:豪华汽车
public class LuxuryCar : ICar
{private ICar car;public LuxuryCar(ICar car){this.car = car;}public void Assemble(){car.Assemble();Console.WriteLine("Adding features of luxury car.");}
}// 客户端代码
class Program
{static void Main(){ICar sportsCar = new SportsCar(new BasicCar());sportsCar.Assemble();  // 组装运动型车Console.WriteLine();ICar sportsLuxuryCar = new LuxuryCar(new SportsCar(new BasicCar()));sportsLuxuryCar.Assemble();  // 组装豪华运动型车}
}

运行结果

Assembling a basic car.
Adding features of sports car.Assembling a basic car.
Adding features of sports car.
Adding features of luxury car.
3. 代理模式 (Proxy Pattern)

目的:代理模式的目的是通过控制访问来间接地管理对某个对象的操作。代理通常是为了控制对真实对象的访问,可以是为了延迟实例化、权限控制或做一些前置处理等。

特点

  • 代理模式的关键是控制对目标对象的访问。代理可以控制目标对象的创建、访问、权限检查等行为。
  • 代理模式的代理类通常实现与被代理类相同的接口,可以通过代理类来调用目标对象的方法。
  • 代理有时用于控制资源的访问,例如通过虚拟代理延迟加载,或者通过安全代理控制对敏感资源的访问。

应用场景

  • 需要在客户端和真实对象之间插入一个代理,以控制对真实对象的访问。
  • 用于懒加载(虚拟代理)、权限控制(保护代理)或日志监控等场景。
示例:C# 代理模式
using System;// 定义接口
public interface IRealSubject
{void Request();
}// 真实对象:实际操作的对象
public class RealSubject : IRealSubject
{public void Request(){Console.WriteLine("Request is being processed by the RealSubject.");}
}// 代理类:控制访问的代理
public class Proxy : IRealSubject
{private RealSubject realSubject;public void Request(){if (realSubject == null){realSubject = new RealSubject();  // 延迟实例化}Console.WriteLine("Proxy: Checking access before forwarding request.");realSubject.Request();  // 转发请求}
}// 客户端代码
class Program
{static void Main(){IRealSubject proxy = new Proxy();proxy.Request();  // 通过代理访问}
}

运行结果

Proxy: Checking access before forwarding request.
Request is being processed by the RealSubject.
4. 装饰器模式与代理模式的区别
方面装饰器模式 (Decorator)代理模式 (Proxy)
目的动态地添加功能或责任,使得对象的行为得到增强。控制对对象的访问,可能会在请求前进行权限检查或懒加载等操作。
行为装饰器改变或扩展对象的行为,不影响原有对象的接口。代理不改变对象的行为,主要用于控制访问权限。
实现方式装饰器是一个封装对象并实现相同接口的类。代理实现与被代理对象相同的接口,控制对对象的访问。
应用场景用于动态地为对象添加功能,通常不涉及对对象访问的控制。用于控制对对象的访问,例如延迟加载、权限控制等。
功能重点扩展功能和责任控制访问(懒加载、权限控制等)
5. 总结

尽管装饰器模式和代理模式看起来很相似,都是通过包装对象来增强或控制对象的行为,但它们有不同的设计目的和使用场景。装饰器模式主要用于增强对象的功能,而代理模式则主要用于控制访问,尤其是延迟加载、权限控制等。理解这两者的区别,可以帮助我们在开发中做出更加合适的设计决策。
在实际开发中,当你需要扩展对象的功能时,可以考虑使用装饰器模式;而当你需要控制对象的访问或者做一些额外的管理时,可以考虑使用代理模式。

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

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

相关文章

纵览!报表控件 Stimulsoft Reports、Dashboards 和 Forms 2025.1 新版本发布!

Stimulsoft 2025.1 新版发布,旨在增强您创建报告、仪表板和 PDF 表单的体验!此最新版本为您带来了许多改进和新功能,使数据处理更加高效和用户友好。亮点包括对 .NET 9 的支持、Microsoft Analysis Services 的新数据适配器、发布向导中适用于…

Unity Pico 应用失去焦点后,追踪功能被禁用(原生 UI 界面弹出)

在 Unity 中,如果正在使用新的输入系统,任何触发 OnApplicationFocus(false) 的事件都可能会禁用追踪功能。 负责此功能的组件是附加到主摄像机的 "Tracked Pose Driver (Input System)" 组件。由于非输入系统版本不是新输入系统的一部分&…

面试准备备备备

职业技能 放到简历的黄金位置(HR刷选简历的重要参考) 基本准则:写在简历上的必须能聊,不然就别写 参考公式:职业技能 必要技术 其他技术 针对性的引导面试官(让他问一些你想让他问的) 寻找合…

多光谱图像的处理和分析方法有哪些?

一、预处理方法 1、辐射校正: 目的:消除或减少传感器本身、大气条件以及太阳光照等因素对多光谱图像辐射亮度值的影响,使得图像的辐射值能够真实反映地物的反射或发射特性。 方法:包括传感器校正和大气校正。传感器校正主要是根…

艾体宝方案丨全面提升API安全:AccuKnox 接口漏洞预防与修复

一、API 安全:现代企业的必修课 在现代技术生态中,应用程序编程接口(API)扮演着不可或缺的角色。从数据共享到跨平台集成,API 成为连接企业系统与外部服务的桥梁。然而,伴随云计算的普及与微服务架构的流行…

多个DataV遍历生成

DataV是数据可视化工具 与Echart类似 相对Echart图标边框 装饰可选官网DataV 安装 npm install kjgl77/datav-vue3main.ts import DataVVue3 from kjgl77/datav-vue3 app.use(DataVVue3)多个DataV遍历生成 Vue3viteDataV为例:<template><div w50rem h25rem flex&qu…

小程序租赁系统的优势与应用探索

内容概要 小程序租赁系统&#xff0c;听起来很高大上&#xff0c;但实际上它比你想象的要实用得多&#xff01;设想一下&#xff0c;几乎所有的租赁需求都能通过手机轻松解决。这种系统的便捷性体现在让用户随时随地都能发起租赁请求&#xff0c;而不再受制于传统繁琐的手续。…

driftingblues2

修改网卡配置信息 首先kali终端运行以下命令查看靶机ip 这里我们发现并没有查到靶机的ip&#xff0c;这时我们重启靶机 打开靶机&#xff0c;按下e键&#xff0c;进入到如下界面 将ro替换为rw signie init/bin/bash 替换完毕后&#xff0c;按下Ctrl键X键&#xff0c;进入如下…

Redis 使用redisTemplate获取某个规则下的key的全量数据(示例Set结构)

如下是redis中存储的数据结构 我想取key以favorites:结尾的所有数据 Redis 的 SCAN 命令用于迭代数据库中的键&#xff0c;支持通过模式过滤结果。模式规则基于 Redis 的通配符匹配语法&#xff0c;类似于文件名匹配规则&#xff1a; *&#xff1a;匹配零个或多个字符。?&…

1月2日作业

工人管理系统 #include<myhead.h> #include<sqlite3.h> sqlite3 * creat_sqlite()//创建数据库并返回数据库句柄 {const char *p"./my.db";sqlite3 *ppDb;if(sqlite3_open(p,&ppDb)!SQLITE_OK)//调用数据库提供的第三方库函数{printf("打开数据…

职场常用Excel基础03-自定义排序

大家好&#xff0c;今天和大家一起分享一下excel中的自定义排序~ 通过排序&#xff0c;用户可以快速地对表格中的数据进行整理&#xff0c;以便更直观地观察趋势、查找特定信息或为后续的数据分析做准备。除了标准的升序和降序排序外&#xff0c;Excel还提供了强大的自定义排序…

计算机网络-L2TP Over IPSec基础实验

一、概述 上次我们进行了标准L2TP的配置&#xff0c;但是在最后我们在进行业务流量访问时看到流量是没有进行加密的&#xff0c;这就导致可能得安全风险&#xff0c;所以这里其实可以退像GRE那样调用IPSec框架来进行加密保护。 拓扑 数据不加密 现在需要配置IPSec&#xff0c;然…

C#控件开发4—仪表盘

目录 思路&#xff08;GDI绘图&#xff09;1.定义属性2.绘制图形3.最后生成&#xff08;自定义各种监控值显示&#xff09;End 如何让温度、湿度、压力等有量程的监控值如仪表盘&#xff08;DashBoard&#xff09;一样显示&#xff1f; 思路&#xff08;GDI绘图&#xff09; 定…

ThinkPHP 8高效构建Web应用-第一个简单的MVC应用示例

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用VS Code开发ThinkPHP项目-CSDN博客 我们先实现一…

数字化供应链创新解决方案在零售行业的应用研究——以开源AI智能名片S2B2C商城小程序为例

摘要&#xff1a; 在数字化转型的浪潮中&#xff0c;零售行业正经历着前所未有的变革。特别是在供应链管理方面&#xff0c;线上线下融合、数据孤岛、消费者需求多样化等问题日益凸显&#xff0c;对零售企业的运营效率与市场竞争力构成了严峻挑战。本文深入探讨了零售行业供应…

RabbitMQ - 4 ( 22000 字 RabbitMQ 入门级教程 )

一&#xff1a; RabbitMQ 高级特性 前面主要讲解了 RabbitMQ 的概念和应用。RabbitMQ 实现了 AMQP 0-9-1 规范&#xff0c;并在此基础上进行了多项扩展。在 RabbitMQ 官方网站中详细介绍了其特性&#xff0c;我们将其中一些重要且常用的特性挑选出来进行讲解。 1.1 消息确认 …

mac m2 安装 docker

文章目录 安装1.下载安装包2.在downloads中打开3.在启动台打开打开终端验证 修改国内镜像地址小结 安装 1.下载安装包 到官网下载适配的安装包&#xff1a;https://www.docker.com/products/docker-desktop/ 2.在downloads中打开 拖过去 3.在启动台打开 选择推荐设置 …

QT--------网络

实现思路 主机信息查询&#xff1a; 使用 QHostInfo 类可以查询主机名和 IP 地址信息。QNetworkInterface 类可以获取本地网络接口的信息&#xff0c;包括 IP 地址、子网掩码、广播地址等。 TCP 通信&#xff1a; 使用 QTcpServer 类实现 TCP 服务器端程序设计。使用 QTcpSock…

智能边缘计算×软硬件一体化:开启全场景效能革命新征程(企业开发者作品)

边缘智能技术快速迭代&#xff0c;并与行业深度融合。它正重塑产业格局&#xff0c;催生新产品、新体验&#xff0c;带动终端需求增长。为促进边缘智能技术的进步与发展&#xff0c;拓展开发者的思路与能力&#xff0c;挖掘边缘智能应用的创新与潜能&#xff0c;高通技术公司联…

docker Error response from daemon

问题 Error response from daemon: Get "https://index.docker.io/v1/search?qnginx&n25": read tcp 192.168.50.233:54354->54.198.86.24:443: read: connection reset by peer Unable to find image redis:latest locally docker: Error response from d…