Composite 组合

将对象组合成树形结构以表示 部分-整体 的层次结构。

比如这样的一个场景(书上的例子): 有text、line这样的一些图元,可以组合成较大的组件。而组合后的组件又可以组合成更大的组件。一种简单的实现,是为text、line定义一些类,另外定义一些类作为这些图元的容器类。这样的问题在于,图元与容器是两类对象,但是实际上组件应当具有图元的性质。

组合composite的关键就是一个抽象类,即可以代表图元,又可以代表图元的容器。

优点:
     1 定义了包含基本对象和组合对象的类层次结构。 基本对象可以被组合成更复杂的组合对象。而组合对象又可以被组合,可以不断进行递归。
     2 简化客户代码,客户可以对单个对象和组合对象不进行区分。
     3 容易增加新的组件
     4 设计变得一般化。 但是也就是意味着很难限制组合中的组件,比如只期望一个组合只能拥有特定的组件,这些只能运行时检查。

这个模式稍微复杂一些,参与者包括:
1 Component 基类
     为所有的的对象声明接口;
      适当情况下实现所有类共以后接口的缺省行为
     声明一个接口用以访问和管理Compoent的子组件
     可以在递归结构中定义一个接口用以访问一个父部件。
2 Leaf 最低层的子类
     在组合中表示叶节点,叶节点没有子节点
     定义叶子节点的行为
3 Composite
     有子部件的那些部件的行为
     存储子部件
     实现Component接口中与子部件有关的操作
3 client 通过Component接口操纵组合部件的对象


Component 的困难主要在于实现出一个良好的体系,实现时需要考虑的地方包括:
1 显式的父部件引用。 通常在Compoent类中定义父部件的引用。 保持从子部件到父部件的引用能简化组合结构的遍历和管理。
          父部件引用,需要保证同一个组合的所有子节点都以这个组合为层次。
2 共享组件 可以减少对存储的需求
     
3 最大化Component接口 Composite模式的目的之一是使得用户不知道他们正在使用的是具体的Leaf和Composite类。为此,Composite应当尽可能的多定义一些公共操作,并通常提供缺省实现。
     而类的层次设计原则规定: 一个类只定义那些对它的子类有意义的操作。这里,访问子节点的接口是Component的一部分,但是对于Leaf类却不需要。
     这里一种解决方法是:为Component定义一个缺省操作,对于子节点进行访问,缺省操作不返回。Leaf类可以使用默认实现,而Composite类则重新实现操作。

4 声明管理子部件的操作
透明性: 在Compoent定义管理子部件的add del方法。可以一致性的使用所有的组件,但是不安全,可能对leaf也使用add、del方法。
安全性: 在Composite类定义管理子部件的方法。这样缺失透明型。 Composite类与Compoent有不同的接口。
这里的一个解决方法是在父类增加Getposite方法,示例如下:

class Composite;
class Component {
public:
     virtual Composite *GetComposite() { return NULL:}
};
class Composite : public Compoent {
     virtual Composite *GetComposite() { return this:}
};
class Leaf : public Compoent {
};



这样对于客户,通过GetComposite来判断是否时候组合,从而选择是否使用管理方法。

提供透明性的唯一方式是在Component类中增加add 、del方法。那么对于Leaf Add会导致失败。可能会和客户的期望不同。

5 Component是否应该实现一个Component列表 在基类中将子节点集合定义为一个变量。但是对于叶节点是空间浪费。

6 子部件排序

7 使用高速缓存改善性能 Composite类可以缓存对其子节点进行遍历或者查找的相关信息。 一旦部件发生变化,父部件的缓存失效。需要顶一个接口来通知父部件缓存信息无效。

8 谁来删除Component 当一个Composite被销毁时,通常最好由Composite负责删除其子节点。

9 存储组件选用的数据结构     Composite的每个子类都可以有自己的 管理接口,自己的存储结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值