本文简单介绍组合模式,以系统文件和文件夹为例。
一、概述
定义:组合模式(Composite pattern)将对象整合到树状结构中来表示整体/部分的层次关系,在树状结构中包括对象和对象组合。组合模式能让客户用一致的方式处理个别对象的对象组合。
1.部分-整体的层级结构以树状结构来表现
2.部分整体的层级结构中,对象和对象组合要以一致方式处理
二、结构
UML:
主要角色:
抽象构件类(Compnent):为所有对象定义了一个接口,无论是叶节点还是组合。
叶构件类(Leaf):继承了抽象构件类,但是没有子构件了,虽然继承了add,remove,getChildren方法,但是对于叶节点来说没什么意义,不过为了保持透明性,我们坚持这么做。
树枝构件类(Component):继承了抽象构件类,持有一个子构件类容器口。
三、系统文件目录
系统文件目录是一个典型的包括叶构件(文件)和树枝构件(文件夹)的组合模式。
当然文件夹和文件操作上还是有区别的,不过,我在这里就让文件夹和文件都实现相同的接口,完成最理想的组合的组合模式——放弃安全性,追求透明性。
定义一个抽象接口,为了保证可以使用户不关心究竟是什么,所有文件/文件夹都要实现这个接口。
1 | public abstract class FileInterface { |
写一个文件夹类
1 | public class Directory implements FileInterface { |
写一个exe文件类
1 | public class ExeFile implements FileInterface { |
这两个类都继承了FileIntercepter抽象类并实现了所有方法,可以等同看待,虽然有些方法并不是两个类都能用的,一定程度上丧失了安全性(程序员调用时需要指到方法的具体实现),不过为了保持透明性(方法同等看待),我们仍选择了全部实现,对于个别方法使用抛出不支持操作异常处理!
下面看测试类
1 | public class Test { |
四、优缺点
优点:
- 组合模式可以很容易的增加新的构件。
- 使用组合模式可以使客户端变的很容易设计,因为客户端可以对组合和叶节点一视同仁。
缺点:
- 使用组合模式后,控制树枝构件的类型不太容易。
- 用继承的方法来增加新的行为很困难。
组合的适用场合:
你想表示对象的部分-整体层次结构。
你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
五、总结
组合模式是对象的结构模式,重点掌握树状结构和将叶节点和组合节点同等看待。
当组合模式与迭代器模式结合时,调用者甚至可以忽略掉组合模式的结构,这里我必须推荐Head First 设计模式中迭代器模式与组合模式这一章,你会发现组合模式与迭代器结合的巨大威力!
此外也有人会为了安全性,将非共性方法不在抽象类中声明,这样虽然安全了,但是调用者就不能将组合模式的叶节点与组合节点同等看待,这并不符合我们的目的,所以我们还是选择本文这种实现方式。
本文首发于cdream个人博客
欢迎转载,转载请注明出处!