MyException - 我的异常网
当前位置:我的异常网» 操作系统 » 重学设计形式 - Composite(组合)模式 - 结构型

重学设计形式 - Composite(组合)模式 - 结构型

www.myexceptions.net  网友分享于:2013-07-20  浏览:4次
重学设计模式 - Composite(组合)模式 - 结构型

1、意图

将对象组合成树形结构以表示“部分 - 整体”的层次结构,Composite使得用户对单个对象和组合对象的使用具有一致性。

2、动机

在图形应用程序中,用户可以使用简单的图元组件组合成较大的组件,这些组件又可以组合成更加复杂的组件。Composite描述了如何使用递归组合,使得用户不必对这些类进行区别。它的关键是一个抽象类,既可以代表简单的图元,又可以代表图元的组合。

3、适用性

  1. 想表示对象的“部分 - 整体”的层次结构
  2. 希望用户忽略组合对象和单个对象的不同,用户将统一使用组合结构中的所有对象。

4、结构

 

5、参与者

  • Component:
    - 为组合中的对象声明接口;
    - 在适当的情况下,实现所有类公共接口的缺省行为;
    - 声明一个接口用于访问和管理Component的子组件;
    - (可选)在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它。
  • Leaf:
    - 在组合中表示叶节点对象,叶节点没有子节点;
    - 在组合中定义其行为。
  • Composite:
    - 定义组合部件的行为;
    - 存储子部件;
    - 实现Component接口中与子部件有关的操作。
  • Client:
    - 通过Component接口操纵所有部件对象。

6、协作

用户使用Component类接口与组合结构中的对象进行交互。如果接收者是一个Leaf,则直接处理请求。如果接收者是Composite,它通常将请求发送给它的子部件,在转发请求之前或/与之后可能执行一些辅助操作。

7、效果

  • 定义了包含基本对象和组合对象的类层次结构。客户端代码中,任何用到基本对象的地方都可以用组合对象。
  • 简化客户端代码。客户可以一致的使用组合对象和单个对象。
  • 更容易增加新类型的组件。
  • 使你的设计变得更加一般化。如果你希望一个组合只能有某些特定的组件。使用Composite时,你不能依赖类型系统施加这些约束,而必须在运行时刻进行检查。

8、实现

  1. 显式的父部件引用。保持“从子部件到父部件的引用”能简化组合结构的遍历和管理。父部件引用可以简化结构的上移和组件的删除,同时父部件引用也支持Chain of Responsibility模式。
    通常在Component类中定义父部件引用。Leaf和Composite类可以继承这个引用以及管理这个引用的那些操作。
    对于父部件的引用,必须维护一个不变式,即一个组合的所有子节点以这个组合为父节点,反之该组合以这些节点为子节点。最容易的办法是,仅当在一个组合中增加或删除一个组件时,才改变这个组件的父部件。
    一句话:在Component基类中增加一个父部件指针,当操作Composite中的Add和Remove时,改变该指针。
  2. 共享组件。共享组件是很有用的,比如可以减少对存储的需求。但是当一个组件只有一个父部件时,很难共享组件。
    一个可行的解决办法是为子部件存储多个父部件,但当一个请求在结构中向上传递时,这种方法对导致多义性。Flyweight模式讨论了如何修改设计以避免将父部件存储在一起。另外,如果子部件可以将一些状态(或所有状态)存储在外部,从而不需要向父部件发送请求,那么这种方法是可行的。
  3. 最大化Component接口。对于仅对Composite类有意义的操作,定义一个某人的缺省实现,Leaf使用缺省实现,Composite重新实现这些操作。
  4. 声明管理子部件的操作。问题:是在Component中声明Add和Remove操作并使之对Leaf类有意义,还是只在Composite中声明并定义这些操作呢?前者具有很好的透明性,可以一致的使用所有的组件,但是客户可能会对Leaf中执行Add和Remove操作;后者具有良好的安全性,但是使Leaf和Composite具有不同的接口,丧失了透明性。
    一种办法是在Component中提供一个Composite* GetComposite()操作,来查询当前组件是不是一个组合,根据返回值安全的执行Add和Remove操作。
    提供透明性的唯一方法是在Component定义缺省的Add和Remove操作。
    提供透明性的唯一方法是在Component中定义缺省的Add和Remove操作,使用缺省方式处理Add和Remove失败(可能是产生一个异常)。Add失败时,可能会造成内存泄露。
  5. Component是否应该实现一个Component列表。在基类中存放子类指针,对于叶节点来说会造成空间浪费,只有当结构中子类数目相对较少时,才值得使用这种方法。
  6. 子部件排序。如果需要考虑子节点的顺序时,必须仔细地设计子节点的访问和管理接口,以便管理子节点序列。参考Iterator模式。
  7. 使用高速缓冲存储改善性能。如果需要对组合进行频繁的遍历和查找,Composite可以缓冲存储对它的子节点进行遍历或查找的相关信息。因此,此时需要定义一个接口来通知父部件它所缓冲存储的信息无效或需要立即更新。
  8. 应该由谁删除Component。在没有垃圾回收机制的语言中,当一个Component被销毁时,通常最好由Composite负责删除其子节点。但有一种情况除外,即Leaf对象不会改变,因此可以被共享。
  9. 存储组件最好使用那一种数据结构。

9、代码示例

10、相关模式

  • 通常部件 - 父部件连接用于Chain of Responsibility模式
  • Decorator模式通常与Composite模式一起使用,它们通常有一个公共的父类。因此Decorator必须支持具有Add、Remove、GetChild等Component接口
  • Flyweight模式让你共享组件,但不再能引用他们的父部件
  • Iterator模式用于遍历Composite
  • Visitor模式将本来应该分布在Composite和Leaf中的操作和行为局部化。

文章评论

60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
程序员和编码员之间的区别
程序员和编码员之间的区别
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
程序员都该阅读的书
程序员都该阅读的书
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
我的丈夫是个程序员
我的丈夫是个程序员
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
老程序员的下场
老程序员的下场
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
鲜为人知的编程真相
鲜为人知的编程真相
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
漫画:程序员的工作
漫画:程序员的工作
旅行,写作,编程
旅行,写作,编程
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
中美印日四国程序员比较
中美印日四国程序员比较
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
编程语言是女人
编程语言是女人
Java程序员必看电影
Java程序员必看电影
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
我是如何打败拖延症的
我是如何打败拖延症的
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
程序员必看的十大电影
程序员必看的十大电影
那些争议最大的编程观点
那些争议最大的编程观点
10个调试和排错的小建议
10个调试和排错的小建议
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
一个程序员的时间管理
一个程序员的时间管理
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
总结2014中国互联网十大段子
总结2014中国互联网十大段子
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
程序员的鄙视链
程序员的鄙视链
如何成为一名黑客
如何成为一名黑客
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有