写这个随笔时,其实对该模式理解的并不是十分透彻。在此想到什么写什么,希望对自己对他人有所帮助。

装饰者模式主要是应用继承和组合的思想,极大的实现了程序的多态,使得的程序有了更高的扩展性。

  第一个基础例子:

这里假如我们要实现有这么一群人,他们都要穿西服。那么我们首先建立这个人类。

  代码如下:

   class Person
{
private string name; //要装扮的人的名称
public Person()
{ }
public Person(string _name)
{
this.name = _name;
}
public virtual void Show() //注意此处是虚方法
{
Console.WriteLine("装扮的人是:{0}", this.name);
}
}

然后构建西服类,代码如下

  class Suit:Person
{
Person component = null; //穿西服的人 public void Decorate(Person _component) //把要穿西服的人传递到该类(组合思想)
{
this.component = _component;
}
public override void Show()
{
//如果有穿西服的人
if (component != null)
{
component.Show();
}
Console.WriteLine("穿上西服");
}
}

假如我们给小明和小红分别穿上西服,Main方法的代码如下

 static void Main(string[] args)
{
Person xiaoming = new Person("小明");
Person xiaohong = new Person("小红");
Suit suit = new Suit(); //装扮小明
suit.Decorate(xiaoming);
suit.Show(); //装扮小红
suit.Decorate(xiaohong);
suit.Show(); Console.ReadKey();
}

运行结果如下

类图结构如下

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第二个基础例子:

假如此时需求变了,我们的不仅要给小明和小红穿西服,我们还要给小狗阿黄穿西服,那该如何修改原程序呢。

开始扩展代码

此时我们新建一个Animal的抽象类

  abstract class Animal  //抽象的Animal类
{
protected string name;
public Animal()
{ }
public Animal(string _name)
{
this.name = _name;
}
public abstract void Show(); //原来Person的虚方法则改为对应的抽象方法
}

然后我们继续新建Person类和Dog类,都继承Animal类

 class Person : Animal  //人类,继承自Animal类
{
public Person(string _name) : base(_name)
{ }
public override void Show() //实现Animal类的抽象方法
{
Console.WriteLine("装扮的人{0}", base.name);
}
}
class Dog : Animal //够类,继承自Animal类
{
public Dog(string _name) : base(_name)
{ }
public override void Show() //实现Animal类的抽象方法
{
Console.WriteLine("装扮的狗{0}", base.name);
}
}

接下来我们分别给小明小红和阿黄穿上西服

 static void Main(string[] args)
{
Person xiaoming = new Person("小明");
Person xiaohong = new Person("小红");
Dog ahuang = new Dog("阿黄"); //装扮小明和小红
Suit suit = new Suit();
suit.Decorate(xiaoming);
suit.Show();
suit.Decorate(xiaohong);
suit.Show();
//装扮阿黄
suit.Decorate(ahuang);
suit.Show(); Console.ReadKey();
}

运行结果如下

类结构图如下,此时我们可以看到人和狗都继承自Animal,实现了一次的扩展的

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

第三个基础例子

此时我们不仅想让小明小红阿黄穿西服了,我们还想让他们穿鞋子,打领带,并且以后可能会有更多的衣服供他们选择(变成奇迹暖暖了);

我们在第二个例子的基础上继续修改,满足需求

此时,我们将原来的Suit类改成抽象的衣服类,然后分别让Suit,Shoes和Sneake类继承自衣服类来实现

首先构造衣服类,代码如下

    class Finery : Animal   //此处继承Animal的抽象类,从而实现了所有类都继承自Animal类,在Derorate组合获得的component的字段,都可以使用Show()方法,从而达到一层一层装扮的目的
{ protected Animal component;
public void Decorate(Animal _component) //注意:此处是组合的思想,主要是为了把要修饰的主体放到该类的component字段中
{
this.component = _component;
}
public override void Show()
{
if (component != null)
{
component.Show();
}
}
}

然后分别构造西服,鞋子,领带类,代码如下

class Sneake : Finery
{
public override void Show()//此处实现的最上层Animal的抽象类
{
base.Show();
Console.WriteLine("系上领带");
}
}
class Shoes : Finery
{
public override void Show()//此处实现的最上层Animal的抽象类
{
base.Show();
Console.WriteLine("穿上鞋子");
}
}
class Suit : Finery
{
public override void Show()//此处实现的最上层Animal的抽象类
{
base.Show();
Console.WriteLine("穿上西服");
}
}

接下来开始给小红小明和阿黄装扮,代码如下

static void Main(string[] args)
{
//实例化所有被装饰的主体
Person xiaoming = new Person("小明");
Person xiaohong = new Person("小红");
Dog ahuang = new Dog("阿黄");
//实例化所有装饰
Suit suit = new Suit();
Sneake sneake = new Sneake();
Shoes shoes = new Shoes(); suit.Decorate(xiaoming);
sneake.Decorate(suit);
shoes.Decorate(sneake);
shoes.Show();
Console.WriteLine();
suit.Decorate(xiaohong);
sneake.Decorate(suit);
shoes.Decorate(sneake);
shoes.Show();
Console.WriteLine();
//狗就不系领带了
shoes.Decorate(ahuang);
suit.Decorate(shoes);
suit.Show(); Console.ReadKey();
}

运行结果如下:

类图结构如下

总结:

装饰者模式的难点在于多继承,存在组合的思想,将最高层次的被继承的类(Animal)组合(Decorate)在装饰类(Finery)中,通过base.Show()方法来一层一层的展现(这点有点绕,很像俄罗斯套娃,需要跟一下程序,一开始不太好理解)。

最后,如果有其他错误,欢迎指出,谢谢

最新文章

  1. 搭建OpenStack,kvm环境准备
  2. AngularJS 页面基本操作
  3. Beats数据采集---Packetbeat\Filebeat\Topbeat\WinlogBeat使用指南
  4. 由easyui的tab在ie下渲染失败,发现的一个有意义的问题
  5. (Beta)Let's-版本发布说明
  6. C#之 HashSet(临时笔记,未参考资料,请慎重)
  7. Attribute 特性
  8. 小记UNIX编程库调用.
  9. Css定位-定位
  10. 空间金字塔池化(Spatial Pyramid Pooling, SPP)原理和代码实现(Pytorch)
  11. Cocoa练习01:一个简单的Todo list程序
  12. javascript语言扩展:可迭代对象(1)
  13. jQuery学习之旅 Item9 动画效果
  14. 使用python对py文件程序代码复用度检查
  15. 动态设置bootstrapswitch状态
  16. iTerm2 与 Oh My Zsh的配套使用
  17. ssdb使用笔记
  18. Installing Android Studio
  19. Java基础-hashMap原理剖析
  20. hiho1270 建造基地([Offer收割]编程练习赛1)

热门文章

  1. Asp.NetCore Web应用程序中的请求管道和中间件
  2. JMeter关联陌生又熟悉
  3. QFNU 10-30 training
  4. font 和 text ,cursor
  5. JAVA的基本介绍和JDK的安装
  6. 最全的go语言的时间格式
  7. istio流量管理:非侵入式流量治理
  8. tigervnc报错
  9. Win10屏幕亮度不能调节,调节无效怎么办?
  10. JNLP配置WIN10