c#装饰器模式详解

这篇具有很好参考价值的文章主要介绍了c#装饰器模式详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基础介绍:

 动态地给一个对象添加一些额外的职责。适用于需要扩展一个类的功能,或给一个类添加多个变化的情况。

  装饰器,顾名思义就是在原有基础上添加一些功能。

  大家都只知道如果想单纯的给原有类增加一些功能,可以直接继续该类生成一个子类就可以。

  举个例子,如果现在有个手机类,想给手机贴膜,传统的做法就是新建一个手机类的子类(手机贴膜子类),继承自手机类。

  使用这个子类就可以完成对手机的贴膜操作。

  那如果又想给手机按保护壳的话,传统做法有两种,可以继续新建一个手机类的子类(手机保护壳子类),继承自手机类。

  使用这个子类可以给手机按保护壳,但也就失去了给手机贴膜的功能。另一种做法,新建一个手机贴膜类的子类(手机贴膜+保护壳),也就是手机类的子子类。

  这样即可以贴膜也可以按手机壳。

  大家思考一个问题,如果有很多个装饰并且想随意组合的话,那就有N个子类并且存在很深的继承链路。

  想要解决这个问题,就可以用到装饰器了。

  比如贴膜装饰、保护壳装饰、贴纸装饰等等,它们都是独立存在的,只继承自装饰器类。

  什么意思呢?就是说给手机贴膜的时候它并不会给手机按保护壳的功能,职责单一,贴膜装饰器只负责给手机贴膜。

  这样做有什么好处呢?好处就是这些装饰可以随意组合,比如即想贴膜又想按保护壳,就可以将贴膜装饰+保护壳装饰进组组合。

  文章来源地址https://www.toymoban.com/news/detail-746117.html

  在装饰器模式中各个角色有:

  • 抽象构件(Component)角色:规范手机的构成
  • 具体构件(ConcreteComponent)角色:继承自抽象构件,具体实现手机。(大多情况下,可以省略抽象构件,抽象装饰类可以直接继承)
  • 抽象装饰类(Decorator)角色:创建一个构件(Component)对象的实例,可以使用这个实例调用原构件的功能,并规范装饰类。
  • 具体装饰类(ConcreteDecorator)角色:继承自抽象装饰类,具体实现该装饰功能。

应用场景:

 原有类无法修改或者修改困难的情况下,对类进行多次扩展或功能性比较相互独立,有效防止多次扩展的情况下子类的膨胀。

  注:如果类的扩展比较简单,并且不会多次进行扩展的情况下直接使用类的继承生成子类的方式更为方便快捷。

创建方式:

 为了方便说明,以下实例就不创建抽象构件了。

  1. 首先先看下不使用装饰器进行类的扩展

     1     /// <summary>
     2     /// 手机类
     3     /// </summary>
     4     public class Phone
     5     {
     6         public void Print()
     7         {
     8             Console.WriteLine("手机");
     9         }
    10     }
    11 
    12     /// <summary>
    13     /// 手机贴膜
    14     /// </summary>
    15     public class Sticker : Phone
    16     {
    17         public Sticker()
    18         {
    19             base.Print();
    20         }
    21 
    22         /// <summary>
    23         /// 进行贴膜
    24         /// </summary>
    25         public void AddSticker()
    26         {
    27             Console.WriteLine("给手机贴膜");
    28         }
    29     }
    30 
    31     /// <summary>
    32     /// 手机保护壳
    33     /// </summary>
    34     public class ProtectiveCase : Phone
    35     {
    36         public ProtectiveCase()
    37         {
    38             base.Print();
    39         }
    40 
    41         /// <summary>
    42         /// 按保护壳
    43         /// </summary>
    44         public void AddProtectiveCase()
    45         {
    46             Console.WriteLine("给手机按保护壳");
    47         }
    48     }
    49 
    50     /// <summary>
    51     /// 即贴膜又按保护壳
    52     /// </summary>
    53     public class ProtectiveCaseAndSticker : Sticker
    54     {
    55         public ProtectiveCaseAndSticker()
    56         {
    57         }
    58 
    59         /// <summary>
    60         /// 按保护壳
    61         /// </summary>
    62         public void AddProtectiveCase()
    63         {
    64             Console.WriteLine("给手机按保护壳");
    65         }
    66     }
    67 
    68     /// <summary>
    69     /// 客户端
    70     /// </summary>
    71     class Client
    72     {
    73         static void Main(string[] args)
    74         {
    75             //创建一个手机
    76             Phone phone = new Phone();
    77             phone.Print();
    78             Console.WriteLine("\r\n");
    79 
    80             //给手机贴膜
    81             Sticker sticker = new Sticker();
    82             sticker.AddSticker();
    83             Console.WriteLine("\r\n");
    84 
    85             //给手机按保护壳
    86             ProtectiveCase protectiveCase = new ProtectiveCase();
    87             protectiveCase.AddProtectiveCase();
    88             Console.WriteLine("\r\n");
    89 
    90             //即贴膜又按保护壳
    91             ProtectiveCaseAndSticker protectiveCaseAndSticker = new ProtectiveCaseAndSticker();
    92             protectiveCaseAndSticker.AddSticker();
    93             protectiveCaseAndSticker.AddProtectiveCase();
    94             Console.ReadKey();
    95         }
    96     }

    c#装饰器模式详解

    通过上述实例可以看出,如果各个扩展功能比较独立的话可以直接进行继承扩展。

    如果各个功能直接有交集的情况下,会造成很深的继承关系。

    比如上述实例中,如果单独贴膜或者单独安装保护壳则直接继承手机类即可。

    但如果想要即贴膜又要安装保护壳,各自继承手机类的方式就行不通了,只能在贴膜类或者保护壳类的基础上进行扩展。

    如果还有添加手机挂饰,那就还需要再一层继承关系。

    要解决这个问题就用到了装饰器,下面看看使用装饰器是怎么给手机添加新功能的。

  2. 使用装饰器模式对类进行扩展

     1     /// <summary>
     2     /// 手机类
     3     /// </summary>
     4     public class Phone
     5     {
     6         public void Print()
     7         {
     8             Console.WriteLine("手机");
     9         }
    10     }
    11 
    12     /// <summary>
    13     /// 装饰抽象类
    14     /// </summary>
    15     public abstract class Decorator : Phone
    16     {
    17         private Phone phone;
    18 
    19         public Decorator(Phone p)
    20         {
    21             this.phone = p;
    22         }
    23 
    24         public abstract void AddDecorator();
    25     }
    26 
    27     /// <summary>
    28     /// 贴膜装饰
    29     /// </summary>
    30     public class Sticker : Decorator
    31     {
    32         public Sticker(Phone p)
    33               : base(p)
    34         {
    35         }
    36 
    37         public override void AddDecorator()
    38         {
    39             Console.WriteLine("给手机贴膜");
    40         }
    41     }
    42 
    43     /// <summary>
    44     /// 保护壳装饰
    45     /// </summary>
    46     public class ProtectiveCase : Decorator
    47     {
    48         public ProtectiveCase(Phone p)
    49              : base(p)
    50         {
    51         }
    52 
    53         /// <summary>
    54         /// 按保护壳
    55         /// </summary>
    56         public override void AddDecorator()
    57         {
    58             Console.WriteLine("给手机按保护壳");
    59         }
    60     }
    61 
    62     /// <summary>
    63     /// 客户端
    64     /// </summary>
    65     class Client
    66     {
    67         static void Main(string[] args)
    68         {
    69             //单独给手机贴膜
    70             Phone phone = new Phone();
    71             phone.Print();
    72             Decorator sticker = new Sticker(phone);
    73             sticker.AddDecorator();
    74 
    75             //单独给手机按保护壳
    76             phone = new Phone();
    77             phone.Print();
    78             Decorator protectiveCase = new ProtectiveCase(phone);
    79             protectiveCase.AddDecorator();
    80             Console.WriteLine("\r\n");
    81 
    82             //即贴膜又按保护壳
    83             phone = new Phone();
    84             phone.Print();
    85             //首先创建贴膜装饰实例,将手机对象传入
    86             Decorator decorator = new Sticker(phone);
    87             //进行贴膜操作
    88             decorator.AddDecorator();
    89             //创建保护壳装饰实例,将贴膜后的手机对象传入
    90             decorator = new ProtectiveCase(decorator);
    91             //进行按保护壳操作
    92             decorator.AddDecorator();
    93             Console.ReadKey();
    94         }
    95     }

    c#装饰器模式详解

    从上述实例中可以看出,各个装饰类只对装饰抽象类负责,职责单一。

    各个装饰进行组合时,方便随意。新增装饰时,只需要新增一个继承自装饰抽象类的子类即可实现以原有装饰的随意组合使用。

总结:

  想要扩展一个类的时候,传统的继承生成子类的形式,适用于扩展简单,并且不会多次扩展的情况下。

  而如果一个类的扩展是周期性,多次扩展的或功能性比较相互独立的情况下,可以使用装饰器,可以有效的解决传统继承扩展子类膨胀的问题。

  装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

  

  

到了这里,关于c#装饰器模式详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 篇八:装饰器模式:动态增加功能

    篇八: “装饰器模式:动态增加功能” 开始本篇文章之前先推荐一个好用的学习工具,AIRIght,借助于AI助手工具,学习事半功倍。欢迎访问:http://airight.fun/。 另外有2本不错的关于设计模式的资料,分享出来与大家学习参考。 链接:https://pan.baidu.com/s/1RmhQF_o1CdK8U7s5KeILog?pwd

    2024年02月14日
    浏览(31)
  • 【C++设计模式】详解装饰模式

    2023年8月31日,周四上午 这是我目前碰到的最难的设计模式..... 非常难以理解而且比较灵活多半,学得贼难受,写得贼费劲..... 2023年8月31日,周四晚上19:48 终于写完了,花了一天的时间来学习装饰模式和写这篇博客。 虽然基本上把我今天的收获都写下来了, 但感觉写得还是

    2024年02月10日
    浏览(23)
  • 设计模式之装饰者模式-TS中装饰器介绍

    装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,访问符,属性或参数上。 装饰器使用@expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入 装饰器分类 装饰器大体上分为: 方法装饰器 类装饰器 属性装饰器

    2024年02月12日
    浏览(23)
  • 【设计模式——学习笔记】23种设计模式——装饰器模式Decorator(原理讲解+应用场景介绍+案例介绍+Java代码实现)

    在咖啡厅中,有多种不同类型的咖啡,客户在预定了咖啡之后,还可以选择添加不同的调料来调整咖啡的口味,当客户点了咖啡添加了不同的调料,咖啡的价格需要做出相应的改变。 要求 :程序实现具有良好的拓展性、改动方便、维护方便 【方案一】 写一个抽象类Drink,然

    2024年02月15日
    浏览(33)
  • Java IO:同步阻塞和装饰器模式详解

    大家好,我是chowley, 今天来介绍一下Java IO中的两个重要概念—— 同步阻塞和装饰器模式。 在计算机编程中,同步阻塞(Synchronous Blocking)指的是在进行某个操作时,当前线程会被阻塞(即暂停执行),直到该操作完成才会继续执行。在 Java IO 中,输入输出操作通常是同步阻

    2024年02月21日
    浏览(24)
  • 【C#基础】C# 面向对象编程

    序号 系列文章 5 【C#基础】C# 运算符总结 6 【C#基础】C# 常用语句讲解 7 【C#基础】C# 常用数据结构 😊大家好,我是writer桑,前面一章已经学习了 C# 中的常用数据结构,那本章就开始学习 C# 程序中面向对象编程的知识,希望看完大家能够有所收获,感谢支持! 面向对象编程

    2024年02月04日
    浏览(43)
  • 状态模式:管理对象状态转换的动态策略

    在软件开发中,状态模式是一种行为型设计模式,它允许一个对象在其内部状态改变时改变它的行为。这种模式把与特定状态相关的行为局部化,并且将不同状态的行为分散到对应的状态类中,使得状态和行为可以独立变化。本文将详细介绍状态模式的定义、实现、应用场景

    2024年04月14日
    浏览(20)
  • 原型模式-克隆一个对象

     在开发一个界面的时候,里面有多个Button,这些对象的属性内容相似。如果一个个实例化Button对象,并设置其属性,那么代码量将会增多。 通过一个原型对象克隆出多个一模一样的对象,该模式被称为原型模式。  图 原型模式 Prototype: 抽象原型类,是声名克隆方法的接口,

    2024年02月16日
    浏览(30)
  • JavaScript代理模式:如何实现对象的动态代理

    在JavaScript中,代理模式是一种常见的设计模式,它允许我们在不改变对象本身的情况下,通过代理对象来控制对象的访问。代理模式可以用于实现缓存、权限控制、远程调用等功能。 代理模式是指在访问对象时引入一定程度的间接性,因为这种间接性可以附加多种用途,所

    2024年02月11日
    浏览(32)
  • JSON对象字符串在C#中进行像sql一样动态查询

    在C#中,我们可以使用多种方法来根据条件动态查询JSON对象字符串数据,类似于SQL语句查询。 使用JObject JObject是Json.NET中的一个类,可以方便地操作JSON对象。通过JObject,我们可以像使用SQL一样使用LINQ查询语句来查询JSON对象。 示例代码: 使用JsonPath JsonPath是一种基于JSON对象

    2023年04月14日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包