F*****e 发帖数: 331 | 1 问题是关于decorate pattern(装饰模式),就是给一个人一件一件穿衣服的程序,基
类是人,第一个子继承类是Finery(服饰),Finery下面有3个子继承类分别是:
Tshirt Sneaker Trousers。 程序中用到了装饰模式的思想,和一堆虚函数和覆写函数
,关于这些函数和覆写函数是怎么跑的我看不明白,贴上代码:请牛人观观!
class Program
{
static void Main(string[] args)
{
Person Alice = new Person("Alice");
Console.WriteLine("\n Alice's beautiful dress are:");
Sneakers sneaker = new Sneakers();
BigTrouser trouser = new BigTrouser();
TShirts tshirt = new TShirts();
sneaker.Decorate(Alice); <-------------------------
trouser.Decorate(sneaker); 就是这一段看不明白!!!!!
tshirt.Decorate(trouser); 虚函数+覆写函数 咋有递归的感觉
tshirt.Show(); <-------------------------
Console.Read();
}
}
class Person //base class
{
private string name;
public Person()
{
}
public Person(string name)
{
this.name = name;
}
public virtual void Show()
{
Console.WriteLine("Decorated person is: {0}", name);
}
}
class Finery : Person
{
protected Person component;
// start decotate
public void Decorate(Person component)
{
this.component = component;
}
public override void Show()
{
if (component != null)
{
component.Show();
}
}
}
class TShirts : Finery
{
public override void Show()
{
Console.Write("Tshirt ");
base.Show();
}
}
class BigTrouser : Finery
{
public override void Show()
{
Console.Write("Trousers ");
base.Show();
}
}
class Sneakers : Finery
{
public override void Show()
{
Console.Write("Sneakers ");
base.Show();
}
}
Alice's beautiful dress are:
Tshirt Trousers Sneakers Decorated person is: Alice
|
v***a 发帖数: 365 | 2 这就是Decorate pattern
tshirt 包含 trouser, trouser 包含 sneaker,...
when you call tshirt.Show();
tshirt 先处理自己的 Write (真正有用的部分), 然后递归调用 trouser.Show()
这也就是关键:
这样 tshirt 就不需要知道 person 到底被多少个Finery decorate,
ANY Finery只需要只要做好自己的工作 和 调用 Base.show() 就可以了,
也就达到了 松耦合:大部分pattern追求的主要目标之一 |
F*****e 发帖数: 331 | 3
,
tshirt 调用 base.Show()后,系统是不是先到person类里 看到是virtual后,再到
Finery类里,然后发现是override 于是继续。。一直跑到trouser类里,然后调用
trouser的show(),然后再base.Show()如此循环??
跑到sneaker的show()的时候为什么不再override到trouser了?
【在 v***a 的大作中提到】 : 这就是Decorate pattern : tshirt 包含 trouser, trouser 包含 sneaker,... : when you call tshirt.Show(); : tshirt 先处理自己的 Write (真正有用的部分), 然后递归调用 trouser.Show() : 这也就是关键: : 这样 tshirt 就不需要知道 person 到底被多少个Finery decorate, : ANY Finery只需要只要做好自己的工作 和 调用 Base.show() 就可以了, : 也就达到了 松耦合:大部分pattern追求的主要目标之一
|
v***a 发帖数: 365 | 4 Finery 类里存了protected Person component;
比如:tshirt 存的 Person 是 trouser;
tshirt 调用 base.Show() 调用的是 Finery 的 show(),然后 Finery 调用的是 他存
的那Person 的 Show(),也就是 Trouser.show(),
然后 recursive
design pattern 的书都有讲的,而且讲得很详细,
说白了就是一个Hook,在调用想要调用的函数之前,先调用你的,然后你再替它调用原
始函数
【在 F*****e 的大作中提到】 : : , : tshirt 调用 base.Show()后,系统是不是先到person类里 看到是virtual后,再到 : Finery类里,然后发现是override 于是继续。。一直跑到trouser类里,然后调用 : trouser的show(),然后再base.Show()如此循环?? : 跑到sneaker的show()的时候为什么不再override到trouser了?
|
q****x 发帖数: 7404 | 5 t-shirt包含trouser?这也太奇怪了。
【在 v***a 的大作中提到】 : 这就是Decorate pattern : tshirt 包含 trouser, trouser 包含 sneaker,... : when you call tshirt.Show(); : tshirt 先处理自己的 Write (真正有用的部分), 然后递归调用 trouser.Show() : 这也就是关键: : 这样 tshirt 就不需要知道 person 到底被多少个Finery decorate, : ANY Finery只需要只要做好自己的工作 和 调用 Base.show() 就可以了, : 也就达到了 松耦合:大部分pattern追求的主要目标之一
|
F*****e 发帖数: 331 | 6
说的很清楚,我很明白了,谢谢!!
【在 v***a 的大作中提到】 : Finery 类里存了protected Person component; : 比如:tshirt 存的 Person 是 trouser; : tshirt 调用 base.Show() 调用的是 Finery 的 show(),然后 Finery 调用的是 他存 : 的那Person 的 Show(),也就是 Trouser.show(), : 然后 recursive : design pattern 的书都有讲的,而且讲得很详细, : 说白了就是一个Hook,在调用想要调用的函数之前,先调用你的,然后你再替它调用原 : 始函数
|
F*****e 发帖数: 331 | 7
我想他的意思不是‘包含’,是说tshirt类去装饰被trouser类装饰好的实例,是先后
关系。
【在 q****x 的大作中提到】 : t-shirt包含trouser?这也太奇怪了。
|
q****x 发帖数: 7404 | 8 还是别扭。t-shirt和trouser应该是平行单位,trouser应该也可以装饰t-shirt。
【在 F*****e 的大作中提到】 : : 我想他的意思不是‘包含’,是说tshirt类去装饰被trouser类装饰好的实例,是先后 : 关系。
|
v***a 发帖数: 365 | 9
当然可以反过来,是平行的概念,这也就是之前说的 decorator pattern的特点,他们
是平行的,松耦合的
只是实现的时候,用了包含,或者说,tshirt 有个指向上级的 pointer, 而 tshirt
不管那个pointer 是谁,也不管tshirt自己本身被谁指向,他只管做完自己的事情之后
,调用 pointer 指向的东西
【在 q****x 的大作中提到】 : 还是别扭。t-shirt和trouser应该是平行单位,trouser应该也可以装饰t-shirt。
|
a****u 发帖数: 1537 | 10 decorate模式目的主要是用对象组合来减少不必要的对象继承关系 |
|
|
q****x 发帖数: 7404 | 11 但是组合应该反映has-a吧?应该是人有衣服,而不是衣服有人。
【在 a****u 的大作中提到】 : decorate模式目的主要是用对象组合来减少不必要的对象继承关系
|
F*****e 发帖数: 331 | 12
衣服包装人(给人穿衣服),如果现在程序需要扩展,不仅给人穿衣服,还要给狗狗穿
衣服,
那么衣服之类的类就不用改,直接写一个狗狗的类,用衣服的类直接去包装狗狗的类。
当然人,狗狗的类上面最好继承一个公共的抽象动物类接口,服装的抽象类也继承那个
接口。
【在 q****x 的大作中提到】 : 但是组合应该反映has-a吧?应该是人有衣服,而不是衣服有人。
|
r****t 发帖数: 10904 | 13 tshirt base 是 finary, 这里和 person 没啥事,就是反复调用 component.show(),
最后 sneaker.component 就是 person Alice 了。
【在 F*****e 的大作中提到】 : : 衣服包装人(给人穿衣服),如果现在程序需要扩展,不仅给人穿衣服,还要给狗狗穿 : 衣服, : 那么衣服之类的类就不用改,直接写一个狗狗的类,用衣服的类直接去包装狗狗的类。 : 当然人,狗狗的类上面最好继承一个公共的抽象动物类接口,服装的抽象类也继承那个 : 接口。
|
r****t 发帖数: 10904 | 14 为啥这里的衣服一定要是 Person 的 subclass? 我想大家疑问是这个。
【在 F*****e 的大作中提到】 : : 衣服包装人(给人穿衣服),如果现在程序需要扩展,不仅给人穿衣服,还要给狗狗穿 : 衣服, : 那么衣服之类的类就不用改,直接写一个狗狗的类,用衣服的类直接去包装狗狗的类。 : 当然人,狗狗的类上面最好继承一个公共的抽象动物类接口,服装的抽象类也继承那个 : 接口。
|
q****x 发帖数: 7404 | 15 可能理解成“穿衣服的人”好一些。
基本上decorator就是个链表。表尾是基类,多一个decoration就多一个元素。
【在 r****t 的大作中提到】 : 为啥这里的衣服一定要是 Person 的 subclass? 我想大家疑问是这个。
|
F*****e 发帖数: 331 | 16
现实中,除了人,还有别的如猫狗,也可以被装扮。人,猫狗都继承一个component类
(比如说),衣服的类也继承component类,那么component就像一个接口,可以用作扩
展,这样就实现了封闭-开放原则和可扩展松耦合的好处。
为了简单起见,我只定义了一个类,就是人person这个类,所以就直接继承了。
【在 r****t 的大作中提到】 : 为啥这里的衣服一定要是 Person 的 subclass? 我想大家疑问是这个。
|
r****t 发帖数: 10904 | 17 这个解释和 code 完全不同,按这个解释,Finary 必须一定不能是 Person 的子类,
算了爱啥啥吧,快学不完了。。。
【在 F*****e 的大作中提到】 : : 现实中,除了人,还有别的如猫狗,也可以被装扮。人,猫狗都继承一个component类 : (比如说),衣服的类也继承component类,那么component就像一个接口,可以用作扩 : 展,这样就实现了封闭-开放原则和可扩展松耦合的好处。 : 为了简单起见,我只定义了一个类,就是人person这个类,所以就直接继承了。
|
q****x 发帖数: 7404 | 18 类型关系是这样:
item, item with decor1, item with decor1 and decor2, item with decor1, 2,
and 3, etc.
【在 r****t 的大作中提到】 : 这个解释和 code 完全不同,按这个解释,Finary 必须一定不能是 Person 的子类, : 算了爱啥啥吧,快学不完了。。。
|
z****u 发帖数: 104 | 19 人可以穿n件衣服,但一件衣服只能穿在一个人身上
所以衣服has-a人,比人has-a衣服更合理吧?
【在 q****x 的大作中提到】 : 但是组合应该反映has-a吧?应该是人有衣服,而不是衣服有人。
|