模式导读:
把部分和整体的关系用树形结构来表示,从而使客户端可以使用统一的方式处理部分对象和整体对象。就像是图书管理员对图书馆的书籍进行整理,既可以对每一部分的书籍进行整理,也可以一次性将它们收集起来然后进行整理。
核心:
抽象构建(Componennt)角色:定义了叶子和容器构建的共同点。
叶子(构建)角色:无子节点。
容器(Composite)构建角色:有容器的特征,可以包含子节点。
工作流程:
1.组合模式为处理树形结构提供了完美的解决方案,描述了如何将容器和叶子进行递归组合,使得用户在使用时可以一致性的对待容器和叶子。
2.当容器对象的指定方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员,并调用执行,其中使用了递归调用的机制对整个结构进行处理。
参考类图:
代码实现:
1.首先定义一个抽象构建类,在其中给定一个抽象方法sort()
1 package com.etc.resolveFolder; 2 //抽象构建 3 public interface SortBooks { 4 void sort();//书籍分类 5 }
2.然后定义叶子构建子类,实现抽象构建类
1 package com.etc.resolveFolder; 2 3 public class ArtBook implements SortBooks{ 4 5 @Override 6 public void sort() { 7 System.out.println("->文学艺术书籍已经整理好!"); 8 } 9 10 }
1 package com.etc.resolveFolder; 2 3 public class ScientificBook implements SortBooks{ 4 5 @Override 6 public void sort() { 7 System.out.println("->科学图书已经整理好!"); 8 } 9 10 }
3.定义容器构建类
1 package com.etc.resolveFolder; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 //容器构建类 7 public class Books implements SortBooks{ 8 //用于存放本容器构建下的子节点 9 private List<SortBooks> list=new ArrayList<SortBooks>(); 10 11 public void add(SortBooks book) { 12 list.add(book); 13 } 14 public void remove(SortBooks book) { 15 list.remove(book); 16 } 17 public SortBooks getChild(int index) { 18 return list.get(index); 19 } 20 21 @Override 22 public void sort() { 23 System.out.println("对各类型书籍开始进行整理。。。"); 24 for(SortBooks book:list) { 25 //利用递归对容器传入的子节点对象进行操作 26 book.sort(); 27 } 28 } 29 }
4.客户端类:
1 package com.etc.resolveFolder; 2 3 public class Client { 4 5 public static void main(String[] args) { 6 //定义一个容器 7 Books bookList=new Books(); 8 9 //定义一个子节点 10 SortBooks b1=new ArtBook(); 11 SortBooks b2=new ScientificBook(); 12 //整理方法实现 13 b1.sort(); 14 b2.sort(); 15 System.out.println("--------------"); 16 bookList.add(b1); 17 bookList.add(b2); 18 bookList.sort(); 19 20 21 } 22 23 }
效果截图:
组合模式的优缺点:
优点:
1、高层模块调用简单。
2、节点自由增加。
缺点:
在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
适用场景:
部分、整体场景,如树形菜单,文件、文件夹的管理。