首页 理论教育 组合模式:生日礼物说明

组合模式:生日礼物说明

时间:2023-11-03 理论教育 版权反馈
【摘要】:第五章生日礼物——组合模式5.1生日礼物时间:12月19日地点:商场人物:大B和他女朋友大B和他的女朋友是大学同学,他们在一起渡过了美好的大学时光。今天又到了女朋友过生日,大B自然要送上礼物以表心意。)5.2组合模式时间:12月19日地点:大B房间人物:大B,小A大B的MM十分之聪明地运用了组合模式,将3件礼物“合成”至1件(套),从而让大B以买一件礼物的方式买了3件礼物。

组合模式:生日礼物说明

第五章 生日礼物——组合模式

5.1 生日礼物

时间:12月19日  地点:商场  人物:大B和他女朋友

大B和他的女朋友是大学同学,他们在一起渡过了美好的大学时光。今天又到了女朋友过生日,大B自然要送上礼物以表心意。

MM:“今天我过生日,你可要送我一件礼物喔!”

大B:“嗯,好吧。今年就好好地补赏你。”

MM:“好,那就要把过去的都补回来喔!”

大B:“好啊,没问题。”

MM:“那你打算怎么补赏我啊?”

大B:“去商店,你自己挑。怎么样?”

MM:“这还差不多。”

大B:“那当然,谁叫我是你男朋友哩。”

MM高兴地拉着大B去逛商店。刚好现在是新贷上市的时候,各式各样的服装,饰品,琳琅满目,而且特别有个性。大B的女朋友看到这个也喜欢,那个也想要,结果什么都想买。

MM:“这件T恤挺漂亮,买,这条裙子好看,买,这个包也不错,买。”

大B:“喂,买了三件了呀!我只答应送一件礼物的哦。”

MM:“什么呀!T恤加裙子加包包 ,正好配成一套呀,小姐,麻烦你包起来。”

大B:“……”(口吐白沫,四肢抽搐,不省人事ing…)

5.2 组合模式

时间:12月19日  地点:大B房间  人物:大B,小A

大B的MM十分之聪明地运用了组合模式,将3件礼物“合成”至1件(套),从而让大B以买一件礼物的方式(反正大B只要付一次钱~~)买了3件礼物。由此不难看出,组合模式将对象以树形结构组织起来,以达到“部分-整体”的层次结构,使得客户(钱包瘪瘪的大B)对单个对象和组合对象(1件vs1套)的使用具有一致性(付一次钱)。

大B:“你知道什么是组合模式吗?”

小A:“嗯,将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。(来自GOF定义)”

大B:“组合模式(又为‘部分-整体’模式)屏蔽了容器对象与单个对象在使用时的差异,为客户端提供统一的操作接口,从而降低客户代码与被调用对象的耦合关系,方便系统的维护与扩展。”

5.3 结构图

大B:“下面是组合模式的结构图如图5-1所示。”

图5-1 结构图

大B:“组合模式为组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理组合模式的子部件。”

Leaf在组合中表示叶节点对象,叶节点没有子节点

Composite定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加Add和删除Remove

客户端代码,能通过Component接口操作组合部件的对象

显示结果:

-root

---leaf A

---leaf B

---Composite X

-----Leaf XA

-----Leaf XB

-----Composite XY

-------Composite XYA

-------Composite XYB

---Leaf c

大B:“现在你能用代码以组合模式,试写一下我给我女朋友买生日礼物。”

小A:“OK”

代码:

大B:“嘿嘿!不错喔!”

5.4 组合模式的使用(www.xing528.com)

小A:“组合模式比较简单,也很容易学习,当你面对一个树形结构的时候,脑筋就该多转一圈:是否可以在该结构中使用组合模式模式?”

大B:“我跟你讲一种简单的方法:定义一个公用的接口,让组合对象和单个对象都去实现该接口。因此,如果面对单个对象,则调用单个对象的方法;如果面对组合对象,递归遍历之,依次调用每个对象的方法;单个对象:相当于树形结构中的叶节点,它不包含任何子对象。”

小A:“如何去实现组合模式模式呢?”

大B:“组合对象相当于树形结构中的枝节点,它可以包含更小的枝对象,也可以包含叶对象。下面的代码是以抽象类定义,一般尽量用接口interface。”

大B:“抽象类Equipment就是Component定义,代表着组合体类的对象们,Equipment中定义几个共同的方法。”

小A:“什么是Disk?”

大B:“Disk是组合体内的一个对象,或称一个部件,这个部件是个单独元素( Primitive)。还有一种可能是,一个部件也是一个组合体,就是说这个部件下面还有‘儿子’,这是树形结构中通常的情况,应该比较轻易理解。”

现在我们先要定义这个组合体:

大B:“上面CompositeEquipment继续了Equipment,同时为自己里面的对象们提供了外部访问的方法,重载Iterator,Iterator是Java的Collection的一个接口,是Iterator模式的实现.”

5.5 适用场景

大B:“当需求中是体现部分与整体层次的结构时,以及希望用户可以忽略组合对象 与单个对象的不同时,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。明白吧?”

小A:“嗯!是的,明白。”

5.6 树

大B:“经常使用Control,你会发现Control有Controls的属性,而Controls集合包含的还是一个Control,类似的还有XmlNode。他们都有一个共有的特性,数据结构都是树行结构。”

小A:“什么是树形模式呢?”

大B:“树(Tree)是n(n≥0)个结点的有限集T,T为空时称为空树,否则它满足如下两个条件:1、有且仅有一个特定的称为根(Root)的结点;2、 其余的结点可分为m(m≥0)个互不相交的子集Tl,T2,…,Tm,其中每个子集本身又是一棵树,并称其为根的子树(SubTree)。”

大B:“上面给出的递归定义刻画了树的固有特性:一棵非空树是由若干棵子树构成的,而子树又可由若干棵更小的子树构成。而这里的子树可以是叶子也可以是分支。先看下一幅图,如图5-2所示,里面的套娃就是一个套着一个的。”

图5-2 套娃

这样一堆娃娃,一个大的套一个小的,小的里面还可以套更小的,所以其组织结构为:

Top toy

-Toy

--toy

---toy

----toy

大B:“如果用程序来描述图5-2套娃,用设计模式的组合模式(Composite)是一个不错的主意。组合模式在GOF中定义为:组合(Composite)模式将对象以树形结构组织起来,以达成‘部分-整体’的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。”

类图如图5-3所示:

图5-3 类图

大B:“可以说,组合模式是比较简单易学的设计模式,我按照其定义和规则,实现一个论坛主题,帖子的组合关系。论坛中,一个主题可以包括很多帖子 ,一个帖子还可以包括很多回复。”

关系是:

Thread

-- Thread||Message

---- Thread||Message

下面是实现文件:

工厂类为:

客户端调用方法为:

类关系图如图5-4所示:

图5-4 类关系图

输结果为:

5.6 组合模式的优点

大B:“说说组合模式的优点吧。”

小A:“组合模式定义了包含基本对象和组合对象的类层次结构。基本对象可以被组合成更复杂的组合 对象,而这个组合对象又可以被组合,这样不断地递归下去,客户代码中,任何用到基本对象的 地方都可以使用组合对象了。 用户不用关心到底是处理一个叶节点还是处理一个组合组件, 也就是用不着为定义组合而写一些选择判断语句了,简单地说就是组合模式让客户可以一致地使用 组合结构和单个对象。”

大B:“嗯,你知道什么是透明方式,什么是安全方式,及他们的好处。”

小A:“ 透明方式也就是说在Component中声明所有用来管理子对象的方法中,其中包括Add、Remove 等。这样实现Component接口的所有子类都具备了Add和Remove。这样做的好处就是叶节点 和枝节点对于外界没有区别,它们具备完全一致的行为接口。但问题也很明显,因为Leaf 类本身不具备Add()、Remove()方法的功能,所以实现它是没有意义的。

安全方式也就是在Component接口中不去声明Add和Remove方法,那么子类的Leaf也不需要去实现它,而是在 Composite声明所有用来管理子类对象的方法。不过由于不透明,所以树叶和树枝将不具有相同的接口, 客户端的调用需要做相应的判断,带来了不便 。”

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈