翼度科技»论坛 编程开发 .net 查看内容

装饰器设计模式这样学,保你必懂!

9

主题

9

帖子

27

积分

新手上路

Rank: 1

积分
27
概述

装饰器模式 允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
简单理解就是动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
我们还是坚持以往的风格,提一个需求,然后用装饰器模式实现一下。
类图


该类图来源网上
装饰器模式主要组成部分

Component:定义一个对象接口,可以给这些对象动态地添加职责;
ConcreteComponent:定义一个对象,继承Component,可以给这个对象添加一些职责;
Decorator:维持一个指向Component的指针,并定义一个与Component接口一致的接口;
ConcreteDecorator:负责向ConcreteComponent添加功能;
在装饰模式中,Decorator定义了一个装饰接口类。因为Decorator与ConcreteComponent继承同一个接口,所以继承Decorator的类ConcreteDecorator可以使用ConcreteComponent的方法,再在ConcreteDecorator里面加入一些新的方法,也就是装饰,就成为了一个包装好的装饰类。
需求

想要一杯奶茶,添加两份布丁,一份珍珠,该如何实现?将来还可能添加更多的配料;
使用装饰器模式的代码
  1. /// <summary>
  2. /// 相当于Component
  3. /// </summary>
  4. public abstract class YinLiao
  5. {
  6.     public abstract double Cast();
  7. }
  8. /*==================茶的种类=====================*/
  9. /// <summary>
  10. /// 相当于ConcreteComponent
  11. /// </summary>
  12. public class MilkTea : YinLiao
  13. {
  14.     public override double Cast()
  15.     {
  16.         Console.WriteLine("奶茶10块钱一杯");
  17.         return 10;
  18.     }
  19. }
  20. /// <summary>
  21. /// 相当于ConcreteComponent
  22. /// </summary>
  23. public class FruitTea : YinLiao
  24. {
  25.     public override double Cast()
  26.     {
  27.         Console.WriteLine("水果茶15块钱一杯");
  28.         return 15;
  29.     }
  30. }
  31. /// <summary>
  32. /// 相当于ConcreteComponent
  33. /// </summary>
  34. public class SodaTea : YinLiao
  35. {
  36.     public override double Cast()
  37.     {
  38.         Console.WriteLine("苏打水4块钱一杯!");
  39.         return 4;
  40.     }
  41. }
  42. /// <summary>
  43. /// 装饰器模式第一个核心
  44. /// </summary>
  45. public abstract class Decorator : YinLiao
  46. {
  47.     /// <summary>
  48.     /// 添加一个父类的引用
  49.     /// </summary>
  50.     private YinLiao yinLiao;
  51.     /// <summary>
  52.     /// 通过set方法赋值
  53.     /// </summary>
  54.     /// <param name="yinLiao"></param>
  55.     public void SetComponent(YinLiao yinLiao)
  56.     {
  57.         this.yinLiao = yinLiao;
  58.     }
  59.     public override double Cast()
  60.     {
  61.         return this.yinLiao.Cast();
  62.     }   
  63. }
  64. /*====================配料类======================================*/
  65. /// <summary>
  66. /// 相当于ConcreteDecorator
  67. /// </summary>
  68. public class BuDing : Decorator
  69. {
  70.     private static double money = 5;
  71.     public override double Cast()
  72.     {
  73.         Console.WriteLine("布丁5块");
  74.         //第二个核心
  75.         return base.Cast() + money;
  76.     }
  77. }
  78. /// <summary>
  79. /// 相当于ConcreteDecorator
  80. /// </summary>
  81. public class Zhenzhu : Decorator
  82. {
  83.     private static double money = 7;
  84.     public override double Cast()
  85.     {
  86.         Console.WriteLine("珍珠7块");
  87.         //第二个核心
  88.         return base.Cast() + money;
  89.     }
  90. }
  91. /// <summary>
  92. /// 相当于ConcreteDecorator
  93. /// </summary>
  94. public class XianCao : Decorator
  95. {
  96.     private static double money = 6;
  97.     public override double Cast()
  98.     {
  99.         Console.WriteLine("仙草6块");
  100.         //第二个核心
  101.         return base.Cast() + money;
  102.     }
  103. }
复制代码
  1. //C#控制台调用
  2. Console.WriteLine("装饰器设计模式!");
  3. /* 茶里面添加两份布丁、一份珍珠*/
  4. MilkTea milkTea = new MilkTea();
  5. BuDing buDing1 = new BuDing();
  6. BuDing buDing2 =new BuDing();
  7. Zhenzhu zhenzhu = new Zhenzhu();
  8. buDing1.SetComponent(milkTea);
  9. buDing2.SetComponent(buDing1);
  10. zhenzhu.SetComponent(buDing2);
  11. Console.WriteLine(zhenzhu.Cast());
复制代码
 zhenzhu.Cast() 执行的顺序为先 zhenzhu.Cast()方法里面的逻辑、 zhenzhu.Cast()方法的bast.cast()又会去执行buDing2.cast()、buDing2.cast()又会去执行buDing1.cast(),直至执行完milkTea.cast(),最后所有的base.cast()逻辑执行完后,返回接着执行zhenzhu.Cast()逻辑结果为27; 
 关于这段控制台调用的代码逻辑比较绕一点,像洋葱一样,一层一层从外面往里面执行。感兴趣的建个控制台调试一把试试。整体类似如下图:

 总结

个人感觉设计模式越往后学越简单,比如像装饰器设计模式说白了就是拓展功能,像上一篇文章我们学习的适配器设计模式就是转换输出。

来源:https://www.cnblogs.com/mhg215/archive/2023/02/23/17145392.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具