首页 > 编程语言 >Decorator 装饰者模式简介与 C# 示例【结构型4】【设计模式来了_9】

Decorator 装饰者模式简介与 C# 示例【结构型4】【设计模式来了_9】

时间:2023-12-27 20:12:46浏览次数:34  
标签:示例 C# IShape 模式 public 对象 添加 设计模式 装饰

Decorator 装饰者模式简介与 C# 示例【结构型4】【设计模式来了_9】

 

阅读目录


回到顶部

〇、简介

1、什么是装饰者模式

一句话解释:

  通过继承统一的抽象类来新增操作,再在使用时通过链式添加到对象中,达到与原有设定无关联可灵活附加。

装饰者模式是一种行为设计模式,它允许向一个现有的对象添加新的行为,同时又不改变其结构。

装饰者模式的基本概念是,将一个对象包装在一个含有对对象进行增强功能的对象中,从而达到对对象扩展功能的目的。

官方意图描述:动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator 模式相比生成子类更为灵活。别名:包装器(wrapper)。

一个比喻:(班级内部毕业晚会,提供各种零食)

   毕业晚会开始了,有很多种零食,陆续由供应商送来,送来一种相当于实现了一次装饰者抽象类,对于使用者每位同学,可以按照自己的需求选择是否装进自己的肚子。

2、优缺点和适用场景

优点:

  • 动态添加功能:装饰者模式允许在运行时为对象添加新的功能,而不需要修改其代码。这使得代码更加灵活和可维护。
  • 代码复用:装饰者模式可以避免代码重复,因为可以在一个对象上添加多个装饰器,而不需要为每个对象都编写新的代码。
  • 易于扩展:装饰者模式可以很容易地添加新的装饰器,而不需要修改现有的代码。
  • 提高代码可读性:装饰者模式可以使代码更加模块化,使得代码更易于理解和维护。

缺点:

  • 过度使用可能导致代码难以理解和维护:装饰者模式可以使代码变得更加灵活,但如果过度使用,可能会导致代码难以理解和维护。
  • 依赖关系增加:装饰者模式会增加对象之间的依赖关系,这可能会导致系统的复杂性增加。
  • 无法改变对象的类:装饰者模式无法改变对象的类,只能在现有类的基础上添加新的功能。这可能会限制了装饰者模式的使用。
  • 性能问题:如果过度使用装饰者模式,可能会导致系统的性能下降。因为在运行时需要动态创建和销毁对象,这可能会消耗大量的系统资源。

适用场景:

  • 在游戏开发中,装饰者模式可以用于为角色添加新的能力和技能,而不影响原先已有的设定。
  • 在UI设计中,装饰者模式可以用于为界面元素添加新的样式和效果,如边框、背景、阴影、动画等。
  • 在图像处理中,装饰者模式可以用于为图像添加新的滤镜和效果,如锐化、模糊、旋转、裁剪等。
  • 在文本处理中,装饰者模式可以用于为文本添加新的格式和效果,如加粗、斜体、下划线、高亮等。
  • 在购物车应用中,装饰者模式可以用于为商品添加新的属性和功能,如价格、库存、优惠券等。
回到顶部

一、通过示例代码简单实现

下面是一段示例代码,假设需要画一个圆,需要设置宽度和颜色:

  // 测试代码
  class Program
  {
  static void Main(string[] args)
  {
  IShape circle = new Circle(); // 准备画个圆
  IShape borderCircle = new BorderDecorator(circle, 2); // 边框宽度设置为 2
  IShape fillCircle = new FillDecorator(borderCircle, "blue"); // 颜色设置为 blue
  fillCircle.Draw(); // 最后开始画
  }
  }
  // 定义一个抽象装饰者接口
  public interface IShape
  {
  void Draw();
  }
  // 定义一个抽象装饰者类
  public abstract class ShapeDecorator : IShape
  {
  protected IShape Shape { get; set; }
  public ShapeDecorator(IShape shape)
  {
  Shape = shape;
  }
  public abstract void Draw();
  }
  // 定义一个具体装饰者类
  public class BorderDecorator : ShapeDecorator
  {
  private readonly int _borderWidth;
  public BorderDecorator(IShape shape, int borderWidth)
  : base(shape)
  {
  _borderWidth = borderWidth;
  }
  public override void Draw()
  {
  Console.WriteLine($"Drawing a {Shape.GetType().Name} with border width {_borderWidth}");
  Shape.Draw();
  }
  }
  // 定义另一个具体装饰者类
  public class FillDecorator : ShapeDecorator
  {
  private readonly string _fillColor;
  public FillDecorator(IShape shape, string fillColor)
  : base(shape)
  {
  _fillColor = fillColor;
  }
  public override void Draw()
  {
  Console.WriteLine($"Drawing a {Shape.GetType().Name} with fill color {_fillColor}");
  Shape.Draw();
  }
  }
  // 定义一个原始形状类
  public class Circle : IShape
  {
  public void Draw()
  {
  Console.WriteLine("Drawing a circle");
  }
  }

下面如果需要增加一个画法该怎么扩展呢?如下代码,增加一个画法的扩展:

  // 再定义另一个具体装饰者类,定义画法
  public class MethodDecorator : ShapeDecorator
  {
  private readonly string _fillColor;
  public MethodDecorator(IShape shape, string fillColor)
  : base(shape)
  {
  _fillColor = fillColor;
  }
  public override void Draw()
  {
  Console.WriteLine($"Drawing a {Shape.GetType().Name} with method {_fillColor}");
  Shape.Draw();
  }
  }
  // 测试代码
  class Program
  {
  static void Main(string[] args)
  {
  IShape circle = new Circle(); // 准备画个圆
  IShape borderCircle = new BorderDecorator(circle, 2); // 边框宽度设置为 2
  IShape fillCircle = new FillDecorator(borderCircle, "blue"); // 颜色设置为 blue
  IShape methodCircle = new MethodDecorator(fillCircle, "clockwise"); // 设计画法顺时针 clockwise
  methodCircle.Draw(); // 最后开始画
  }
  }

这就是装饰者模式的基本思想:通过将一个对象包装在一个含有对对象进行增强功能的对象中,从而达到对对象扩展功能的目的。

回到顶部

二、装饰者模式的结构

根据上一章节的示例代码,可得如下结构图:

IShape:定义一个对象接口,可以给这些对象动态地添加职责。

Cricle:定义一个对象,可以给这个对象添加一些职责。

ShapeDecorator:维持一个指向 IShape 对象的指针,并定义一个与 IShape 接口一致的抽象类。

BorderDecorator、FillDecorator:向  Cricle 对象添加职责。

回到顶部

三、相关模式

关于适配器模式 Adapter:Decorator 模式不同于 Adapter 模式,因为装饰仅改变对象的职责而不改变它的接口;而适配器将给对象一个全新的接口。

关于组合模式 Composite:可以将装饰视为一个退化的、仅有一个组件的组合。然而,装饰仅给对象添加一些额外的职责————它的目的不在于对象聚集。

关于策略模式 Strategy:装饰者模式改变的是对象的外表;而 Strategy 模式使得你可以改变对象的内核。这是改变对象的两种途径。

本文来自博客园,作者:橙子家,微信号:zfy1070491745,有任何疑问欢迎沟通,一起成长! 您的支持,博主的动力!

标签:示例,C#,IShape,模式,public,对象,添加,设计模式,装饰
From: https://www.cnblogs.com/sexintercourse/p/17931330.html

相关文章

  • misc( 9 )
    黑客帝国脚本将16进制转为二进制流转存为flag.rarimportbinasciihex_data='txt文件中16进制数据'out=open('flag.rar','wb')out.write(binascii.unhexlify(hex_data))out.close()运行脚本得到flag.rar压缩包,ARCHPR爆破压缩包密码为:3690打开图片发现提示文件格式错误,01......
  • C# 9.0 添加和增强的功能【基础篇】
    C#9.0添加和增强的功能【基础篇】 阅读目录一、记录(record)with表达式二、仅限Init的资源库三、顶级语句四、模式匹配增强功能五、模块初始值设定(ModuleInitializer)六、可以为null的引用类型规范七、目标类型的new表达式八、扩展分部方法九、静态匿名......
  • C# Replace:一个熟悉而又陌生的替换
    C#Replace:一个熟悉而又陌生的替换 阅读目录前言一、String.Replace()的几个重载1、Replace(Char,Char)2、String.Replace(String,String) 3、Replace(String,String,StringComparison)4、Replace(String,String,Boolean,CultureInfo)二、Regex.Replace......
  • [App Service for Windows]通过 KUDU 查看 Tomcat 配置信息
    问题描述在AppService中选择了JavaTomcat后,如何查看AzureAppService的Tomcat的配置信息呢? 问题解答可以通过以下的3个步骤查看: 第一步:登录Kudu:方式一:在当前Web应用的URL中加入 .scm (插入位置在site名与chinacloudsites之间)。方式二:在当前Web应用......
  • [EFI]Lenovo Thinkpad W541电脑 Hackintosh 黑苹果efi引导文件
    硬件型号驱动情况主板LenovoThinkpadW541处理器Intel®Core™i7-4800MQ已驱动内存16GBDDR3L1600MHz已驱动硬盘KingstonA400512gb已驱动显卡Intel®HDGraphics4600已驱动声卡RealtekALC292已驱动有线网卡Intel®EthernetConnectionI217已驱动无线网卡+蓝牙Intel®Wi......
  • Sqoop连接数据库报错:Caused by: javax.net.ssl.SSLHandshakeException: No appropriat
    控制台报错:[[email protected]__hadoop-2.0.0-alpha]#./bin/sqooplist-databases--connectjdbc:mysql://192.168.45.10:3306--usernameroot--password1234562023-12-2802:58:50,807WARNtool.BaseSqoopTool:Settingyourpasswordonthecommand-linei......
  • rcs群发软件系统功能设计与应用,rcs群发软件系统,rcs群发软件
    随着科技的不断发展,人们对于通讯方式的需求也在不断变化,传统的短信、电话已经无法满足人们对于高效、便捷、实时的通讯需求,正是在这样的背景下,富通讯解决方案(RichCommunicationSuite,简称RCS)应运而生。RCS是一种基于IP的多媒体消息服务,它为用户提供了一种新的通讯方式,使得消息......
  • 11 ADC模块FEP-DAQ422X采集显示波形方案
    软件版本:VIVADO2021.1操作系统:WIN1064bit硬件平台:适用XILINXA7/K7/Z7/ZU/KU系列FPGA登录米联客(MiLianKe)FPGA社区-www.uisrc.com观看免费视频课程、在线答疑解惑!1概述本方案通过把DAQ422X采集到的数据,通过前面已经完成的示波器显示驱动进行在屏幕上显示ADC采集的波形数据......
  • 基于Spring Boot2.x 集成 Spring Cloud Gateway
    参考https://blog.csdn.net/DCTANT/article/details/108125229(boot与cloud的版本关系)https://blog.csdn.net/yuanchangliang/article/details/109579705https://blog.csdn.net/qq_38380025/article/details/102968559本文代码下载环境环境版本说明windows1......
  • ETCD 下线Member未剔除引发的日志报错
    背景介绍容器化的etcd集群原来具有三个节点分别为etcd-0,etcd-1,etcd-2,在节点etcd-2下线后剩两个节点etcd-0,etcd-1#kubectlgetpod-napisixNAMEREADYSTATUSRESTARTSAGEetcd-0......