Head First Design patterns笔记-Decorator Patterns (从”用不同技能武装自己”看装饰模式)
定义:Decorator patterns attach additional responsibilities abilities(我自己加的) to an object dynamically, decorators provide a flexible alternative to subclassing for extending functionality.
背景介绍:学习是人类与生俱来的一种能力。当然像哭泣、微笑、吃饭、睡觉等能力人一来到这个世界就会。当你学习了一种技能你就会多一种行为能力。用不同的技能把自己武装起来,你就会成为一个”多才多艺”的人,^_^。就我自己而言,吃喝拉撒睡这些就不用再提了,小学四年纪的时候学会了游泳(在同伴当中应该算是学的很晚的),大约六年级的时候开始摸篮球,算起球龄来也差不多15年了,不能算高手中的低手至少也应该算是低手中的高手了(大学的时候也是靠球技迷倒一片的,^_^。稍微自恋一下)。大学修的计算机科学与技术,毕业来北京混饭吃做了一年多的开发。后来走投无路做了一年测试,最后还是脱离了枯燥的测试工作重新做开发。算起来这几项能力我也算都具备了,现在除了做好自己的开发工作,我也会协助同事做一些测试的工作,工作之余我会参加一些游泳,篮球的比赛活动,业余时间教我老婆这几项技能,^_^。这篇文章的例子正是模拟人与技能之间的这种关系,我的一个朋友一直做开发,现在正在学习游泳,基本不会打球,这个例子把他拉进来吧!^_^。
VS自动生成的类图:
VS自动生成的类图看起来还真不大习惯,下次可能用PD了。^_^。
实例代码:
1
using System;2
using System.Collections.Generic;3
using System.Text;4

5
namespace DecoratorDemo6


{7

/**//// <summary>8
/// Both subject and decorator all implment this interface.9
/// </summary>10
public interface IHuman11

{12
void Learn();13
}14

15

/**//// <summary>16
/// Decorator base class, all concrete decorator classes implement this interface.17
/// We create this class in order to make the hierarchy more clear.18
/// </summary>19
public interface SkillBase : IHuman20

{21

22
}23

24

/**//// <summary>25
/// Concrete subject to decorate.26
/// </summary>27
public sealed class ConcreteHuman : IHuman28

{29
public void Learn()30

{31
Console.WriteLine("Crying, laughing, eating,etc. are our natural skills!");32
}33
}34

35

36
public sealed class TestingSkill : SkillBase37

{38
IHuman _human;39
public TestingSkill(IHuman human)40

{41
_human = human;42
}43

44
public void Learn()45

{46
_human.Learn();47
Console.WriteLine("I have been a tester for more than one year,i know what kinds of skills one tester should have.");48
}49

50
}51
public sealed class DevelopingSkill : SkillBase52

{53
IHuman _human;54
public DevelopingSkill(IHuman human)55

{56
_human = human;57
}58

59
public void Learn()60

{61
_human.Learn();62
Console.WriteLine("After my graduation, I became a prefessional developer.");63
}64
}65

66
public sealed class SwimmingSkill : SkillBase67

{68
IHuman _human;69
public SwimmingSkill(IHuman human)70

{71
_human = human;72
}73

74
public void Learn()75

{76
_human.Learn();77
Console.WriteLine("I mastered swimming skill when i was in my primary school.");78
}79
}80

81
public sealed class BasketballSkill : SkillBase82

{83
IHuman _human;84
public BasketballSkill(IHuman human)85

{86
_human = human;87
}88

89
public void Learn()90

{91
_human.Learn();92
Console.WriteLine("More than 15 years basketball playing experience.");93
}94
}95

96

/**//// <summary>97
/// Testing driver.98
/// </summary>99
class Program100

{101
static void Main(string[] args)102

{103
Console.WriteLine("Do you want to have my information? Take a look at the lines below:");104
Console.WriteLine("***********************************************************");105
IHuman myself = new ConcreteHuman();106
myself = new DevelopingSkill(myself);107
myself = new TestingSkill(myself);108
myself = new SwimmingSkill(myself);109
myself = new BasketballSkill(myself);110
myself.Learn();111

112
Console.WriteLine("***********************************************************");113
Console.WriteLine(Environment.NewLine);114
Console.WriteLine("The following is the information of my friend.");115
Console.WriteLine("***********************************************************");116
117
IHuman myFriend = new ConcreteHuman();118
myFriend = new DevelopingSkill(myFriend);119
myFriend = new SwimmingSkill(myFriend);120
myFriend.Learn();121
Console.WriteLine("***********************************************************");122

123
Console.ReadKey();124
}125
}126
}127

运行结果图:
本例引出的面向对象原则:
类可以用来扩展,但是不应该被修改。(classes should be open for extension but closed for modification.)
此外本例也体现了面向接口编程的思想,在decorator的具体实现中应用了一个IHuman对象,而不是应用ConcreteHuman对象正说明了这一点。如果你想扩展subject的功能,那你就实现自己的decorator就可以,无需修改subject内的任何代码。
代码下载:
DecoratorDemo.zip
后续:
装饰模式最最关键的一点是主体(subject)和修饰者(decorator)应该有共同的接口,对于本例而言就是ConcreteHuman 和SkillBase两个类都继承自IHuman这个接口。

