定义:
把多个对象组成树状结构来表示局部与整体,这样用户可以一样的对待单个对象和对象的组合。
组合模式的通过树形结构来描述单个对象和对象组合,通过迭代的方式获取节点下的子节点,同时通过一个高度抽象的接口使用户可以一致的操作单个对象和对象组合,简化客户端的工作。
同时由于使用树状结构,可以灵活添加、删除节点,而不用改动过客户端代码。
定义角色:
文档打印:
希望将一些优秀的文档打印出来。由于文档比较多,所以又为他们进行分类。通过组合模式,打印机只要调用print方法就可以把需要的文档都打印出来。
component:
public interface IDoc { public int getCount(); //文档的数量 public void print(); //打印 public boolean add(IDoc doc); //添加一个子节点(枝/叶) public boolean remove(IDoc doc); //移除一个子节点 }
composite:
public class Folder implements IDoc { private List<IDoc> folder = new ArrayList<IDoc>(); public int getCount() { int count = 0; for(IDoc doc : folder) count += doc.getCount(); return count; } public void print() { for(IDoc doc : folder) doc.print(); } public boolean add(IDoc doc) { return folder.add(doc); } public boolean remove(IDoc doc) { return folder.remove(doc); } }
leaf:
叶节点是无法添加节点的,所以出于安全目的,当调用叶节点中关于子节点操作的方法时会抛出异常。
public class Document implements IDoc { private String docName; public Document(String docName) { this.docName = docName; } public int getCount() { return 1; } public void print() { System.out.println(docName); } public boolean add(IDoc doc) { throw new RuntimeException("叶节点无法添加文档..."); } public boolean remove(IDoc doc) { throw new RuntimeException("叶节点无法删除文档..."); } }
最后看下客户端的调用:
public class Client { public static void main(String[] args) { Folder composite = new Folder(); composite.add(new Document("Java学习笔记")); Folder folder = new Folder(); folder.add(new Document("组合模式学习笔记(上)")); folder.add(new Document("组合模式学习笔记(下)")); composite.add(folder); System.out.println("打印文档的数量为:" + composite.getCount()); composite.print(); } }
输出结果:
打印文档总数:3
Java学习笔记
组合模式学习笔记(上)
组合模式学习笔记(下)
如果下次想添加几篇文档再打印时,打印机仍然只要调用print方法就可以了。