设计模式-结构型-装饰者模式

装饰者模式(wrapper):

  允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰器模式是一种用于代替继承的技术,无需通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。

示例:英雄学习技能

1 public class Program  2 {  3     private static void Main(string[] args)  4     {  5         //选择英雄  6         Hero hero = new BlindMonk();  7         Skills skills = new Skills(hero);  8         Skills r = new Skill_R(skills, "猛龙摆尾");  9         Skills e = new Skill_E(r, "天雷破/摧筋断骨"); 10         Skills w = new Skill_W(e, "金钟罩/铁布衫"); 11         Skills q = new Skill_Q(w, "天音波/回音击"); 12         //学习技能 13         q.learnSkill(); 14     } 15 } 16  17 /// <summary> 18 /// Component 英雄接口 19 /// </summary> 20 public interface Hero 21 { 22     void learnSkill(); 23 } 24  25 /// <summary> 26 /// ConcreteComponent 具体英雄盲僧 27 /// </summary> 28 public class BlindMonk : Hero 29 { 30     public void learnSkill() 31     { 32         Console.WriteLine($"盲僧学习了以上技能!"); 33     } 34 } 35  36 /// <summary> 37 /// Decorator 技能栏 38 /// </summary> 39 public class Skills : Hero 40 { 41     private Hero hero; 42  43     public Skills(Hero hero) 44     { 45         this.hero = hero; 46     } 47  48     public virtual void learnSkill() 49     { 50         if (hero != null) 51             hero.learnSkill(); 52     } 53 } 54  55 /// <summary> 56 /// ConreteDecorator 技能:Q 57 /// </summary> 58 public class Skill_Q : Skills 59 { 60     private string _skillName; 61  62     public Skill_Q(Hero hero, string skillName) : base(hero) 63     { 64         this._skillName = skillName; 65     } 66  67     public override void learnSkill() 68     { 69         Console.WriteLine($"学习了技能Q:{this._skillName}"); 70         base.learnSkill(); 71     } 72 } 73  74 /// <summary> 75 /// ConreteDecorator 技能:W 76 /// </summary> 77 public class Skill_W : Skills 78 { 79     private string _skillName; 80  81     public Skill_W(Hero hero, string skillName) : base(hero) 82     { 83         this._skillName = skillName; 84     } 85  86     public override void learnSkill() 87     { 88         Console.WriteLine($"学习了技能W:{this._skillName}"); 89         base.learnSkill(); 90     } 91 } 92  93 /// <summary> 94 /// ConreteDecorator 技能:E 95 /// </summary> 96 public class Skill_E : Skills 97 { 98     private string _skillName; 99 100     public Skill_E(Hero hero, string skillName) : base(hero)101     {102         this._skillName = skillName;103     }104 105     public override void learnSkill()106     {107         Console.WriteLine($"学习了技能E:{this._skillName}");108         base.learnSkill();109     }110 }111 112 /// <summary>113 /// ConreteDecorator 技能:R114 /// </summary>115 public class Skill_R : Skills116 {117     private string _skillName;118 119     public Skill_R(Hero hero, string skillName) : base(hero)120     {121         this._skillName = skillName;122     }123 124     public override void learnSkill()125     {126         Console.WriteLine($"学习了技能R:{this._skillName}");127         base.learnSkill();128     }129 }

装饰者模式有四个角色:

  

  1)抽象构建(Component ):给出一个抽象接口,来规范被添加职责的对象;

  2)具体构件(ConcreteComponent):定义一个将要接收附加责任的具体对象;

  3)装饰抽象类(Decorator):持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口;

  4)具体装饰对象(ConreteDecorator):负责给构件对象 ”贴上“附加的责任。起到给Component添加职责的功能。

要点:

  1)装饰者和被装饰对象有相同的超类型。

  2)可以用一个或多个装饰者包装一个对象。

  3)装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的。

  4)对象可以在任何时候被装饰,所以可以在运行时动态的,不限量的用你喜欢的装饰者来装饰对象。

  5)装饰模式中使用继承的关键是想达到装饰者和被装饰对象的类型匹配,而不是获得其行为。

  6)装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。在实际项目中可以根据需要为装饰者添加新的行为,做到“半透明”装饰者。

.NET中装饰者的使用:

MemoryStream memoryStream = new MemoryStream(new byte[] {95,96,97,98,99}); // 扩展缓冲的功能BufferedStream buffStream = new BufferedStream(memoryStream);// 添加加密的功能CryptoStream cryptoStream = new CryptoStream(memoryStream,new AesManaged().CreateEncryptor(),CryptoStreamMode.Write);// 添加压缩功能GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Compress, true);  

装饰者模式的优缺点:

  优点:1)装饰这模式和继承的目的都是扩展对象的功能,但装饰者模式比继承更灵活;

     2)通过使用不同的具体装饰类以及这些类的排列组合,设计师可以创造出很多不同行为的组合;

      3)装饰者模式有很好地可扩展性

  缺点:装饰者模式会导致设计中出现许多小对象,如果过度使用,会让程序变的更复杂。并且更多的对象会是的差错变得困难,特别是这些对象看上去都很像。

装饰者模式与代理模式的区别:

  1)两种模式的关注点不同,装饰者模式关注的是在一个对象上动态的添加方法,而代理模式关注的是控制对象的访问。

  2)装饰者模式可以让使用者直观的看到增强了哪些功能,而代理模式完全限制了使用者,只去调用代理,至于代理里面增加了什么功能,使用者是不知道,隐藏了一个对象的具体信息,这正是为什么代理模式在初始化时不能像装饰模式一样传入一个原始对象的参数的原因。

  3)代理和真实对象之间的的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造。

参考:https://www.cnblogs.com/jaredlam/archive/2011/11/08/2241089.html  

   https://www.cnblogs.com/zhili/p/DecoratorPattern.html

   https://blog.csdn.net/lxt610/article/details/81009089

(0)

相关推荐

  • 设计模式:装饰者模式

    装饰者模式 概述 我们先来看一个快餐店的例子. 快餐店有炒面.炒饭这些快餐,可以额外附加鸡蛋.火腿.培根这些配菜,当然加配菜需要额外加钱,每个配菜的价钱通常不太一样,那么计算总价就会显得比较麻烦. 使 ...

  • DercoratorPattern装饰者模式

    装饰者模式 1,定义 动态的给一个对象添加一些额外的职责. 装饰者模式通常有4个角色,就增加功能来说,装饰者模式比生成子类更加的灵活. Component:抽象构件.通常是一个接口或者抽象类,定义最核 ...

  • PHP设计模式之装饰器模式

    PHP设计模式之装饰器模式 工厂模式告一段落,我们来研究其他一些模式.不知道各位大佬有没有尝试过女装?据说女装大佬程序员很多哟.其实,今天的装饰器模式就和化妆这件事很像.相信如果有程序媛MM在的话,马 ...

  • 设计模式-结构型模式总结

    结构型模式主要处理类或对象的组合,关注于如何将现有类或对象组织在一起形成更大的结构. 适配器模式 将一个类的接口转换成客户希望的另外一个接口,使原本不能一起工作的类可以一起工作. 适配器模式属于补偿机 ...

  • 每天学习一个设计模式(二):结构型之桥梁模式

    一.基本概念 桥梁模式(Bridge)是对象的结构模式.又称为柄体(Handle and Body)模式或接口(Interface)模式.桥梁模式的用意是"将抽象化(Abstraction) ...

  • 设计模式-结构型-桥接模式

    桥接模式(Bridge): 桥接是用于把抽象化与实现化解耦,使得两者可以独立变化. 桥接模式的角色: 1)抽象化角色(Abstraction):它是用于定义抽象接口,通常是抽象类而不是接口,其中定义了 ...

  • 结构型设计模式 - 装饰者模式详解

    基本定义 装饰者模式属于结构型模式,它可以动态的将新功能附加到对象上,同时又不改变其结构.在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(OCP). 模式结构 装饰者和被装饰者有相同 ...

  • 无废话设计模式(11)结构型模式--代理模式

    0-前言 代理模式定义:为其他对象提供一种代理以控制对这个对象的访问. 1-实现 1-1.简单UML图: 1-2.代码实现 //1.抽象父类 abstract class Actor { public ...

  • 无废话设计模式(10)结构型模式--外观模式

    0-前言 外观模式定义:为子系统中的一组接口提供一个一致的界面,此模式定了一个高层接口    这一接口使得这一子系统更加容易使用: 1-实现 1-1.简单UML图: 1-2.代码实现 //1.子系统A ...

  • 无废话设计模式(9)结构型模式--享元模式

    0-前言 享元模式定义:运用共享技术有效地支持大量细粒度的对象. 1-实现 1-1.简单UML图:  1-2.代码实现 //1.抽象父类(网站父类) abstract class Website { ...

  • 结构型设计模式 - 组合模式详解

    基本介绍 1.组合模式(Composite Pattern)又叫部分整体模式,他创建了对象组的树形结构,将对象组合成树状结构以表示「整体 - 部分」的层次关系. 2.组合模式使得用户对单个对象和组合对 ...

  • 设计模式-装饰器模式

    装饰器模式 定义 装饰器模式也叫包装模式 在不改变原有对象的基础上,把功能附加到对象上,提供了比继承更有弹性的替代方案 能够扩展原有对象的功能 属于结构型模式 生活中的例子 买煎饼 我们煎饼可以加鸡蛋 ...