楼主

68916发表于 2019-11-28 13:48:29
只看该作者楼主

【综合】【码手设计-2】给面加鸡蛋 [复制链接]

作者:HW-HM


先看一个“给面加鸡蛋”的例子。

研发食堂供应各种面,宽面、细面、拉面等都有,你可以随便选。选好面之后,在师傅煮面的时候,你可以告诉他要加哪些东西,你可以加鸡蛋、牛肉、排骨等,你想加啥就加啥,你也可以啥都不加,也可以啥都加。你如何设计软件面馆,以方便吃面的人想加啥就加啥?

实现代码如下:

[code lang='cpp']
#include 'stdafx.h'
class Noodle
{
public:
virtual void Print() = 0;
};

class Adder: public Noodle
{
public:
Adder(Noodle* pNoodle)
{
this->pNoodle = pNoodle;
}
protected:
Noodle* pNoodle;
};

class EggAdder: public Adder
{
public:
EggAdder(Noodle* pNoodle):Adder(pNoodle)
{}
void Print()
{
pNoodle->Print();
printf('Egg added\n');
}
};

class BeafAdder: public Adder
{
public:
BeafAdder(Noodle* pNoodle):Adder(pNoodle)
{}
void Print()
{
pNoodle->Print();
printf('Beaf added\n');
}
};

class ThickNoodle: public Noodle
{
public:
void Print()
{
printf('Thick Noodle\n');
}
};

class ThinNoodle: public Noodle
{
public:
void Print()
{
printf('Thin Noodle\n');
}
};

int main()
{
ThickNoodle thickNoodle;
//加鸡蛋
Noodle* pEggAdded = new EggAdder(&thickNoodle);
ThinNoodle thinNoodle;
pEggAdded->Print();
//先加牛肉,再加鸡蛋
Noodle* pBeafAndEggAdded = new EggAdder(new BeafAdder(&thinNoodle));
pBeafAndEggAdded->Print();
return 0;
}
[/code]

运行结果如下:

1.jpg

这就是装饰模式,Noodle是面条基类(接口),ThickNoodleThinNoodle分别是细面和粗面;Adder就是装饰基类(接口),EggAdderBeafAdder分配加鸡蛋和牛肉。对于一碗面,加了鸡蛋之后,还是一碗面,Adder继承了Noodle,保证了这一点,这使得加了蛋之后,还可以加别的东西,因为还是一碗面。鸡蛋、牛肉这些东西是怎么加进去的呢?我们注意到Adder聚合了成员pNoodle,指明了待添加东西的面(可能已经添加过别的东西了),通过调用“pNoodle->Print(); printf('Egg added\n');”,先把面呈上来,再把鸡蛋加进去。如果你要再加一个鸡蛋,把刚才加了鸡蛋的面再用EggAdder装饰一把就可以了。接下来给出装饰模式的定义:

装饰模式动态地给一个对象添加一些额外的职责。通过继承被装饰的接口,使得被装饰后还可继续装饰(也就是面加了鸡蛋之后还是面),通过聚合来复用被装饰的功能(pNoodle指向要加料的面)达到了动态添加职责的效果。对应的类结构图如下:

2.jpg

这里如果使用继承,则达不到动态装饰的效果,有多少种加料方法,就得有多少子类,因为继承的复用是“焊”上去的,子类和父类的关系是绑死的,儿子只能复用老爹的功能,这种关系在编译时就确定了,称之静态绑定。而聚合的复用是“贴”上去的,谁让我贴我就贴,这个谁是在运行时决定的,称之为动态绑定。这就引出组合/聚合复用原则:

在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用这些对象的目的。

应首先使用合成/聚合,合成/聚合则使系统灵活,其次才考虑继承,达到复用的目的。如果两个类是“Has-a”关系应使用合成、聚合,如果是“Is-a”关系可使用继承。'Is-A'是严格的分类学意义上定义,意思是一个类是另一个类的'一种'。而'Has-A'则不同,它表示某一个角色具有某一项责任。

举报
发表于 2019-11-28 13:49:57
只看该作者沙发

好帖子好比喻

举报
楼主发表于 2019-11-28 16:51:17
只看该作者板凳

欢迎大家批评指正

举报
楼主发表于 2019-11-28 16:51:25
只看该作者地板
举报
楼主发表于 2019-11-28 16:51:36
只看该作者5 #
举报
楼主发表于 2019-11-28 16:51:48
只看该作者6 #
举报
楼主发表于 2019-11-28 16:51:59
只看该作者7 #
举报
楼主发表于 2019-11-28 16:52:11
只看该作者8 #
举报
楼主发表于 2019-11-28 16:52:28
只看该作者9 #
举报
楼主发表于 2019-11-28 16:52:42
只看该作者10 #
举报

您需要登录后才可以回帖

登录注册
发表回复