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

  • 装饰器设计模式这样学,保你必懂!已关闭评论
  • 146 次浏览
  • A+
所属分类:.NET技术
摘要

装饰器模式 允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。


概述

装饰器模式 允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

简单理解就是动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。

我们还是坚持以往的风格,提一个需求,然后用装饰器模式实现一下。

类图

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

该类图来源网上

装饰器模式主要组成部分

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

ConcreteComponent:定义一个对象,继承Component,可以给这个对象添加一些职责;

Decorator:维持一个指向Component的指针,并定义一个与Component接口一致的接口;

ConcreteDecorator:负责向ConcreteComponent添加功能;

在装饰模式中,Decorator定义了一个装饰接口类。因为Decorator与ConcreteComponent继承同一个接口,所以继承Decorator的类ConcreteDecorator可以使用ConcreteComponent的方法,再在ConcreteDecorator里面加入一些新的方法,也就是装饰,就成为了一个包装好的装饰类。

需求

想要一杯奶茶,添加两份布丁,一份珍珠,该如何实现?将来还可能添加更多的配料;

使用装饰器模式的代码

/// <summary> /// 相当于Component /// </summary> public abstract class YinLiao {     public abstract double Cast(); }  /*==================茶的种类=====================*/ /// <summary> /// 相当于ConcreteComponent /// </summary> public class MilkTea : YinLiao {     public override double Cast()     {         Console.WriteLine("奶茶10块钱一杯");         return 10;     } } /// <summary> /// 相当于ConcreteComponent /// </summary> public class FruitTea : YinLiao {     public override double Cast()     {         Console.WriteLine("水果茶15块钱一杯");         return 15;     } } /// <summary> /// 相当于ConcreteComponent /// </summary> public class SodaTea : YinLiao {     public override double Cast()     {         Console.WriteLine("苏打水4块钱一杯!");         return 4;     } }  /// <summary> /// 装饰器模式第一个核心 /// </summary> public abstract class Decorator : YinLiao {     /// <summary>     /// 添加一个父类的引用     /// </summary>     private YinLiao yinLiao;     /// <summary>     /// 通过set方法赋值     /// </summary>     /// <param name="yinLiao"></param>     public void SetComponent(YinLiao yinLiao)     {         this.yinLiao = yinLiao;     }     public override double Cast()     {         return this.yinLiao.Cast();     }    }  /*====================配料类======================================*/ /// <summary> /// 相当于ConcreteDecorator /// </summary> public class BuDing : Decorator {     private static double money = 5;     public override double Cast()     {         Console.WriteLine("布丁5块");         //第二个核心         return base.Cast() + money;     } }  /// <summary> /// 相当于ConcreteDecorator /// </summary> public class Zhenzhu : Decorator {     private static double money = 7;     public override double Cast()     {         Console.WriteLine("珍珠7块");         //第二个核心         return base.Cast() + money;     } } /// <summary> /// 相当于ConcreteDecorator /// </summary> public class XianCao : Decorator {     private static double money = 6;     public override double Cast()     {         Console.WriteLine("仙草6块");         //第二个核心         return base.Cast() + money;     } }

//C#控制台调用 Console.WriteLine("装饰器设计模式!"); /* 茶里面添加两份布丁、一份珍珠*/ MilkTea milkTea = new MilkTea(); BuDing buDing1 = new BuDing(); BuDing buDing2 =new BuDing();  Zhenzhu zhenzhu = new Zhenzhu(); buDing1.SetComponent(milkTea); buDing2.SetComponent(buDing1); zhenzhu.SetComponent(buDing2); 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; 

 关于这段控制台调用的代码逻辑比较绕一点,像洋葱一样,一层一层从外面往里面执行。感兴趣的建个控制台调试一把试试。整体类似如下图:

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

 总结

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