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

news/2025/1/8 9:42:01/

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.ppmy.cn/news/1560710.html

相关文章

【面试AI算法题中的知识点】方向涉及:ML/DL/CV/NLP/大数据...本篇介绍Tensor RT 的优化流程。

【面试AI算法题中的知识点】方向涉及:ML/DL/CV/NLP/大数据…本篇介绍Tensor RT 的优化流程。 【面试AI算法题中的知识点】方向涉及:ML/DL/CV/NLP/大数据…本篇介绍Tensor RT 的优化流程。 文章目录 【面试AI算法题中的知识点】方向涉及:ML/D…

搭建开源版Ceph分布式存储

系统:Rocky8.6 三台2H4G 三块10G的硬盘的虚拟机 node1 192.168.2.101 node2 192.168.2.102 node3 192.168.2.103 三台虚拟机环境准备 1、配置主机名和IP的映射关系 2、关闭selinux和firewalld防火墙 3、配置时间同步且所有节点chronyd服务开机自启 1、配置主机名和…

Python 语言实现 IP 地址转换

以下是使用 Python 语言实现 IP 地址转换相关功能的资源示例,包含了 IP 地址十进制与二进制相互转换以及 IP 地址整数表示与点分十进制表示相互转换的代码及解释 IP 地址十进制与二进制相互转换 十进制 IP 转二进制 IP 在 Python 中,我们可以利用ipaddr…

音视频-----RTSP协议 音视频编解码

流媒体协议详解:RTSP、RTP、RTCP、SIP、SDP、RTMP、WebRTC、WebSocket-CSDN博客 上文讲解比较清楚 多媒体编解码基础知识 一文详解WebRTC、RTSP、RTMP、SRT-腾讯云开发者社区-腾讯云 RTP :(Real-time Transport Protocol)是用于Internet上针对多媒体数据流的一种传…

我用AI学Android Jetpack Compose之开篇

最近突发奇想,想学一下Jetpack Compose,打算用Ai学,学最新的技术应该要到官网学,不过Compose已经出来一段时间了,Ai肯定学过了,用Ai来学,应该问题不大,学习过程记录下来,…

计算机毕业设计Django+Tensorflow音乐推荐系统 音乐可视化 卷积神经网络CNN LSTM音乐情感分析 机器学习 深度学习 Flask

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

Webpack学习笔记(9)

Shimming预置依赖 预置全局变量 例如lodash: 细颗粒度shimming 当模块运行在commonjs上下文中,this指向的是module.exports并不是window,所以可以覆盖一下。 安装npm i imports-loader -D 配置后this指向window: 全局Exports 全局导出一…

【Go学习】-01-3-函数 结构体 接口 IO

【Go学习】-01-3-函数 结构体 接口 IO 1 函数1.1 函数概述1.1.1 函数做为参数1.1.2 函数返回值 1.2 参数1.3 匿名函数1.4 闭包1.5 延迟调用1.6 异常处理 2 结构体2.1 实例化2.2 匿名结构体2.3 匿名字段 3 类方法3.1 接收器3.2 类方法练习:二维矢量模拟玩家移动3.3 给…