设计模式——装饰模式
Posted 苹果园dog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式——装饰模式相关的知识,希望对你有一定的参考价值。
一、简介
装饰模式(Decorator)又名包装器(Wrapper),属于结构型模式的一种,采用递归的思想,用于包装类,使其功能丰富。
例如:有一个统计图表控件,可能需要有图/表切换的功能(切换按钮),也可能需要添加一个下拉框,用于过滤统计图表某个指标,
这些附加的功能根据不同的应用场景而不同,此时可以考虑采用装饰模式,动态为原始统计图表对象添加功能。
二、类图(引用GoF)
Component是原型类,被装饰的对象;
ConcreteComponet继承于Component,具体原型类;
Decorator是装饰基类,用于装饰Component,继承于Component,且拥有(关联)一个Component对象;
ConcreteDecoratorA和ConcreteDecoratorB为Decorator的派生类。
三、例子
在实际应用中,可以灵活运用装饰模式,可以没有具体原型类,也可以没有装饰基类。
下面通过一组例子详细介绍其用法。
1、装饰原型类的方法,为方法添加功能(包含具体原型类和装饰基类)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 装饰模式 { //=============================装饰方法SetA()================================ /// <summary> /// 原型类 /// </summary> public class BaseObject0 { private string a; public virtual void SetA() { } } public class DrivedObject0 : BaseObject0 { public override void SetA() { base.SetA(); } } /// <summary> /// 装饰基类 /// </summary> public class DecorateBase0 : BaseObject0 { private BaseObject0 obj = null; public DecorateBase0(BaseObject0 boj) { this.obj = boj; } public override void SetA() { if (obj!=null) { obj.SetA(); } } } //============================================================= /// <summary> /// 装饰子类A /// </summary> public class Adecorate0 : DecorateBase0 { public Adecorate0(BaseObject0 boj) : base(boj) { } public override void SetA() { base.SetA(); Console.WriteLine("Adecorate0" + System.Environment.NewLine); } } //============================================================ /// <summary> /// 装饰子类B /// </summary> public class Bdecorate0 : DecorateBase0 { public Bdecorate0(BaseObject0 boj) : base(boj) { } public override void SetA() { base.SetA(); Console.WriteLine("Bdecorate0" + System.Environment.NewLine); } } }
调用:
Bdecorate0 bdecorate = new Bdecorate0(new Adecorate0(new BaseObject0())); bdecorate.SetA(); Console.ReadKey();
结果:
2、通过方法装饰类的字段或属性(不包含具体原型类和装饰基类)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 装饰模式 { //=============================装饰字段a================================ /// <summary> /// 原型类 /// </summary> public class BaseObject4 { public string a; public virtual void SetA() { } } /// <summary> /// 装饰基类 /// </summary> public class DecorateBase4:BaseObject4 { protected BaseObject4 obj = null; public DecorateBase4(BaseObject4 boj) { this.obj = boj; } } //============================================================= /// <summary> /// 装饰子类A /// </summary> public class Adecorate4 : DecorateBase4 { public Adecorate4(BaseObject4 boj) : base(boj) { } public override void SetA() { obj.SetA(); a = obj.a + "Adecorate" + System.Environment.NewLine; } } //============================================================ /// <summary> /// 装饰子类B /// </summary> public class Bdecorate4 : DecorateBase4 { public Bdecorate4(BaseObject4 boj) : base(boj) { } public override void SetA() { obj.SetA();//Adecorate4(obj)的a的值为"Adecorate" a = obj.a + "Bdecorate" + System.Environment.NewLine; } } }
调用:
Bdecorate4 bdecorate = new Bdecorate4(new Adecorate4(new BaseObject4())); bdecorate.SetA(); Console.WriteLine(bdecorate.a); Console.ReadKey();
效果同上
3、装饰方法(包含装饰基类,不包含具体原型类)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 装饰模式 { /// <summary> /// 原型类 /// </summary> public class BaseObject { private string a; public virtual string GetA() { return a; } } /// <summary> /// 装饰基类 /// </summary> public class decorator : BaseObject { BaseObject obj = null; public decorator(BaseObject bojPara) { this.obj = bojPara; } public override string GetA() { return obj.GetA(); } } /// <summary> /// 装饰子类A /// </summary> public class Adecorate : decorator { public Adecorate(BaseObject boj) :base(boj) { } public override string GetA() { return base.GetA() + "Adecorate"; } } /// <summary> /// 装饰子类B /// </summary> public class Bdecorate : decorator { public Bdecorate(BaseObject boj) : base(boj) { } public override string GetA() { return base.GetA() + "Bdecorate"; } } }
调用:
Bdecorate bdecorate = new Bdecorate(new Adecorate(new BaseObject())); Console.WriteLine(bdecorate.GetA()); Console.ReadKey();
效果同上
4、装饰方法(不包含装饰基类和具体原型类)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 装饰模式 { /// <summary> /// 原型类 /// </summary> public class BaseObject2 { private string a; public virtual string GetA() { return a; } } /// <summary> /// 装饰类A /// </summary> public class Adecorate2:BaseObject2 { BaseObject2 obj = null; public Adecorate2(BaseObject2 boj) { this.obj = boj; } public override string GetA() { return obj.GetA() + "Adecorate" + System.Environment.NewLine; } } /// <summary> /// 装饰类B /// </summary> public class Bdecorate2 : BaseObject2 { BaseObject2 obj = null; public Bdecorate2(BaseObject2 boj) { this.obj = boj; } public override string GetA() { return obj.GetA() + "Bdecorate" + System.Environment.NewLine; } } }
调用:
Bdecorate2 bdecorate = new Bdecorate2(new Adecorate2(new BaseObject2())); Console.WriteLine(bdecorate.GetA()); Console.ReadKey();
效果同上。.
5、通过方法装饰字段或属性(无装饰基类和具体原型类)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 装饰模式 { /// <summary> /// 原型类 /// </summary> public class BaseObject3 { public string a; public virtual void SetA() { } } //============================================================= /// <summary> /// 装饰类A /// </summary> public class Adecorate3 : BaseObject3 { BaseObject3 obj = null; public Adecorate3(BaseObject3 boj) { this.obj = boj; } public override void SetA() { obj.SetA(); a = obj.a + "Adecorate" + System.Environment.NewLine; } } //============================================================ /// <summary> /// 装饰类B /// </summary> public class Bdecorate3 : BaseObject3 { BaseObject3 obj = null; public Bdecorate3(BaseObject3 boj) { this.obj = boj; } public override void SetA() { obj.SetA();//Adecorate3(obj)的a的值为"Adecorate" a=obj.a + "Bdecorate" + System.Environment.NewLine; } } }
调用:
Bdecorate3 bdecorate = new Bdecorate3(new Adecorate3(new BaseObject3())); bdecorate.SetA(); Console.WriteLine(bdecorate.a); Console.ReadKey();
方法同上。
以上是关于设计模式——装饰模式的主要内容,如果未能解决你的问题,请参考以下文章