首页 > 代码库 > OO模式-Composite
OO模式-Composite
组合模式也叫做“部分-整体”模式,这样其实定义也就很明显了,正好和数据结构的知识相对应,把对象组合成树形结构以表示“部分-整体”的层次结构。
先看类图:
首先分析一下这个类图,Leaf和Composite是同辈的,都是继承父类Component,又因为Component中存在Leaf子类,所以他和Component还存在着聚合关系
举一个很常见的例子,我们天天对着电脑,和各种文件,文件夹打交道,这不就是一个很好地组合模式吗?
来看看类图:
来看看具体的实现代码:
AbstractFile为组合中的对象声明接口,实现所有类共有接口的默认行为。
package composite; import java.util.*; //添加引用 public abstract class AbstractFile { protected String name; // 定义name字段 public void printName() { System.out.println(name); } // 通常都用add和remove方法来提供增加或移除树叶或树枝的功能 public abstract boolean addChild(AbstractFile file); // 增加 public abstract boolean removeChild(AbstractFile file); // 移除 // 一个集合,存放摘要文件的子文件的对象 public abstract List<AbstractFile> getChildren(); }File为子类文件,继承父类,也是树中所谓的叶子节点,叶子节点是没有子节点的,所以父类所谓的方法并不能实现,返回true和null
package composite; import java.util.*; public class File extends AbstractFile { public File(String name) { this.name = name; } //文件并没有添加的能力,它只是一个单独的个体 public boolean addChild(AbstractFile file) { return false; } //对于文件本身,已经是叶子节点了,所以也无删除子文件的功能 public boolean removeChild(AbstractFile file) { return false; } // 由于File已经是叶子节点了,所以就不存在集合这一说,所以这个方法返回的是空值 public List<AbstractFile> getChildren() { return null; } }Folder为子类文件夹,同样也继承于父类,但是此类只是一个普通的节点,里边依旧包含叶子节点。
package composite; import java.util.*; public class Folder extends AbstractFile { private List<AbstractFile> childList ; public Folder(String name) { this.name = name; //用来建立一个集合保存子文件 this.childList = new ArrayList<AbstractFile>(); } //添加子文件 public boolean addChild(AbstractFile file) { return childList.add(file); } //删除子文件 public boolean removeChild(AbstractFile file) { return childList.remove(file); } // 子类的返回类型应该和父类的定义保持一致 public List<AbstractFile> getChildren() { return childList; } }最后来看看客户端是如何调用和打印的
package composite; import java.util.List; public class Client { public static void main(String[] args) { // TODO 自动生成的方法存根 // 构造一个树形的文件、目录结构 AbstractFile rootFolder = new Folder("c:\\"); AbstractFile compositeFolder = new Folder("composite"); AbstractFile windowsFolder = new Folder("windows"); AbstractFile file = new File("TestComposite.java"); rootFolder.addChild(compositeFolder); rootFolder.addChild(windowsFolder); compositeFolder.addChild(file); // 打印目录文件树 printTree(rootFolder); } private static void printTree(AbstractFile ifile) { ifile.printName(); List<AbstractFile> children = ifile.getChildren(); if (children == null) return; for (AbstractFile file : children) { printTree(file); // 打印方法的调用 } } }
透明方式与安全方式
在File子类中,他所谓的各种方法都是不实行的,但是却依旧存在,这种方式就叫做“透明方式”;这样做的好处就是叶子节点和枝节点对于外界没有区别,它们具备完全一致的行为接口;但是问题也会很明显的,那就是在File中那些所谓的方法的存在是毫无意义的;如果不想让其做无用功,也就是把File子类中的无意义的方法都去掉,这种方式叫做“安全方式”;但是由于是不透明的,所以他们就不能具有一致的接口了,这样反而增加了其复杂性,客户端的调用需要再增加其相应的判断。
什么时候使用组合模式?
1)需求中体现的是“部分-整体”的层次的结构时,使用此模式;
2)用户希望忽略组合对象与单个对象的不同,统一地使用组合结构中的所有的对象的时候,使用此模式;
最后总结:
每个模式其实都是需要慢慢理解的,真正的懂得了它的精髓所在,那当再看到类似的字眼的时候就会有亲近的感觉,对于组合模式总结为以下几点:
- 组合模式提供一个结构,可同时包容个别对象和组合对象;
- 允许客户对个别对象以及组合对象一视同仁;
- 组合结构内的任意对象都称为组件,组件可以是组合,也可以是叶子节点;
- 在实现组合模式时,有许多设计上的折衷。这时候就要就情况选择透明方式还是安全方式了!
OO模式-Composite
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。