一、基本概念
1、组合模式(Composite),将对象组合成树形结构以表示“部分-整体”的层次结构,用户对单个对象和组合对象的使用具有一致性。主要是体现一致性。分为安全模式和透明模式。
2、角色
A、Component: 抽象构件
B、Leaf: 叶子构件
C、Composite: 容器构件
D、Client: 客户类
3、组合模式有两种不同的实现,分别为透明模式和安全模式,
二、简单例子
1、透明模式
A、Component: 抽象构件
1 package comm.pattern.struct.composite; 2 3 /** 4 * 5 * @Title: Component.java 6 * @Package: comm.pattern.struct.composite 7 * @Description: 抽象容器,展示文件目录 8 * @author yangzhancheng 9 * @2020年3月21日:下午11:11:36 10 * 11 */ 12 public abstract class Component { 13 14 protected String name; 15 16 public Component(String name) { 17 this.name = name; 18 } 19 20 //增加一个叶子构件或树枝构件-叶子节点为文件,树枝构建为目录 21 public abstract void add(Component component); 22 23 //删除一个叶子构件或树枝构件-叶子节点为文件,树枝构建为目录 24 public abstract void remove(Component component); 25 26 //获取分支下的所有叶子构件和树枝构件-叶子节点为文件,树枝构建为目录 27 public abstract void display(int depth); 28 29 }
B、Leaf: 叶子构件
1 package comm.pattern.struct.composite; 2 3 /** 4 * 5 * @Title: Leaf.java 6 * @Package: comm.pattern.struct.composite 7 * @Description: 透明模式下-叶子节点(文件) 8 * @author yangzhancheng 9 * @2020年3月21日:下午11:18:05 10 * 11 */ 12 public class FileLeaf extends Component { 13 14 public FileLeaf(String name) { 15 super(name); 16 } 17 18 @Override 19 public void add(Component component) { 20 // 空实现,这里主要是安全模式的区别,实际为抛出异常 21 } 22 23 @Override 24 public void remove(Component component) { 25 // 空实现,这里主要是安全模式的区别,实际为抛出异常 26 } 27 28 @Override 29 public void display(int depth) { 30 // 输出树形结构的叶子节点,无下一个级别 31 for (int i = 0; i < depth; i++) { 32 if (i < depth - 1) { 33 System.out.print(' '); 34 } else { 35 System.out.print('+'); 36 } 37 } 38 System.out.println(name); 39 } 40 }
C、Composite: 容器构件
1 package comm.pattern.struct.composite; 2 3 import java.util.ArrayList; 4 5 /** 6 * 7 * @Title: Composite.java 8 * @Package: comm.pattern.struct.composite 9 * @Description: 透明模式下-树杈节点(目录) 10 * @author yangzhancheng 11 * @2020年3月21日:下午11:12:41 12 * 13 */ 14 public class FloderComposite extends Component { 15 16 //构建容器 17 private ArrayList<Component> componentArrayList = new ArrayList<Component>(); 18 19 public FloderComposite(String name) { 20 super(name); 21 } 22 23 @Override 24 public void add(Component component) { 25 this.componentArrayList.add(component); 26 } 27 28 @Override 29 public void remove(Component component) { 30 this.componentArrayList.remove(component); 31 } 32 33 @Override 34 public void display(int depth) { 35 //输出树形结构 36 for(int i=0; i<depth; i++) { 37 if(i<depth-1){ 38 System.out.print(' '); 39 }else{ 40 System.out.print('+'); 41 } 42 43 } 44 45 System.out.println(name); 46 47 //下级遍历 48 for (Component component : componentArrayList) { 49 component.display(depth + 1); 50 } 51 } 52 53 }
D、Client: 客户类
1 package comm.pattern.struct.composite; 2 3 /** 4 * 5 * @Title: Client.java 6 * @Package: comm.pattern.struct.composite 7 * @Description: 描述该文件做什么 8 * @author yangzhancheng 9 * @2020年3月21日:下午11:20:23 10 * 11 */ 12 public class Client { 13 14 public static void main(String[] args) { 15 // 创建根节点及其子节点 16 FloderComposite root = new FloderComposite("00.工作目录"); 17 root.add(new FileLeaf("01.需求文档.doc")); 18 root.add(new FileLeaf("02.项目计划.xls")); 19 20 // 创建第二层节点及其子节点 21 FloderComposite branch = new FloderComposite("03.成员日报"); 22 branch.add(new FileLeaf("0301.李四的日报.doc")); 23 branch.add(new FileLeaf("0302.王五的日报.doc")); 24 root.add(branch); 25 26 // 创建第三层节点及其子节点 27 FloderComposite branchDate = new FloderComposite("0303.张三日报目录"); 28 branchDate.add(new FileLeaf("01.张三日报_20200304.doc")); 29 branchDate.add(new FileLeaf("02.张三日报_20200305.doc")); 30 branch.add(branchDate); 31 32 // 创建第二层节点 33 root.add(new FileLeaf("04.验收报告.doc")); 34 35 // 创建第二层节点并删除 36 FileLeaf leaf = new FileLeaf("05.其他"); 37 root.add(leaf); 38 root.remove(leaf); 39 40 // 打印 41 root.display(1); 42 } 43 }
运行结果
+00.工作目录 +01.需求文档.doc +02.项目计划.xls +03.成员日报 +0301.李四的日报.doc +0302.王五的日报.doc +0303.张三日报目录 +01.张三日报_20200304.doc +02.张三日报_20200305.doc +04.验收报告.doc
2、安全模式
主要体现在Component中的add,remove下放到容器构建中,而不是叶子节点中,因为叶子节点不需要这样的操作。
A、Component: 抽象构件
1 package comm.pattern.struct.composite.ex; 2 3 /** 4 * 5 * @Title: Component.java 6 * @Package: comm.pattern.struct.composite 7 * @Description: 抽象容器,展示文件目录 8 * @author yangzhancheng 9 * @2020年3月21日:下午11:11:36 10 * 11 */ 12 public abstract class Component { 13 14 protected String name; 15 16 public Component(String name) { 17 this.name = name; 18 } 19 //获取分支下的所有叶子构件和树枝构件 20 public abstract void display(int depth); 21 }
B、Leaf: 叶子构件
1 package comm.pattern.struct.composite.ex; 2 3 import java.util.ArrayList; 4 5 /** 6 * 7 * @Title: Composite.java 8 * @Package: comm.pattern.struct.composite 9 * @Description: 安全模式下-树杈节点(目录) 10 * @author yangzhancheng 11 * @2020年3月21日:下午11:12:41 12 * 13 */ 14 public class FloderComposite extends Component { 15 16 // 构建容器 17 private ArrayList<Component> componentArrayList = new ArrayList<Component>(); 18 19 public FloderComposite(String name) { 20 super(name); 21 } 22 23 public void add(Component component) { 24 this.componentArrayList.add(component); 25 } 26 27 public void remove(Component component) { 28 this.componentArrayList.remove(component); 29 } 30 31 public void display(int depth) { 32 //输出树形结构 33 for(int i=0; i<depth; i++) { 34 if(i<depth-1){ 35 System.out.print(' '); 36 }else{ 37 System.out.print('+'); 38 } 39 40 } 41 42 System.out.println(name); 43 44 //下级遍历 45 for (Component component : componentArrayList) { 46 component.display(depth + 1); 47 } 48 } 49 50 }
C、Composite: 容器构件
1 package comm.pattern.struct.composite.ex; 2 3 /** 4 * 5 * @Title: Leaf.java 6 * @Package: comm.pattern.struct.composite 7 * @Description: 安全模式下-叶子节点(文件) 8 * @author yangzhancheng 9 * @2020年3月21日:下午11:18:05 10 * 11 */ 12 public class FileLeaf extends Component { 13 14 public FileLeaf(String name) { 15 super(name); 16 } 17 18 @Override 19 public void display(int depth) { 20 // 输出树形结构的叶子节点 21 for (int i = 0; i < depth; i++) { 22 if (i < depth - 1) { 23 System.out.print(' '); 24 } else { 25 System.out.print('+'); 26 } 27 } 28 System.out.println(name); 29 } 30 }
D、Client: 客户类
1 package comm.pattern.struct.composite.ex; 2 3 import comm.pattern.struct.composite.FileLeaf; 4 import comm.pattern.struct.composite.FloderComposite; 5 6 /** 7 * 8 * @Title: Client.java 9 * @Package: comm.pattern.struct.composite 10 * @Description: 展示安全的组合模式 11 * @author yangzhancheng 12 * @2020年3月21日:下午11:20:23 13 * 14 */ 15 public class Client { 16 17 public static void main(String[] args) { 18 // 创建根节点及其子节点 19 FloderComposite root = new FloderComposite("00.工作目录"); 20 root.add(new FileLeaf("01.需求文档.doc")); 21 root.add(new FileLeaf("02.项目计划.xls")); 22 23 // 创建第二层节点及其子节点 24 FloderComposite branch = new FloderComposite("03.成员日报"); 25 branch.add(new FileLeaf("0301.李四的日报.doc")); 26 branch.add(new FileLeaf("0302.王五的日报.doc")); 27 root.add(branch); 28 29 // 创建第三层节点及其子节点 30 FloderComposite branchDate = new FloderComposite("0303.张三日报目录"); 31 branchDate.add(new FileLeaf("01.张三日报_20200304.doc")); 32 branchDate.add(new FileLeaf("02.张三日报_20200305.doc")); 33 branch.add(branchDate); 34 35 // 创建第二层节点 36 root.add(new FileLeaf("04.验收报告.doc")); 37 38 // 创建第二层节点并删除 39 FileLeaf leaf = new FileLeaf("05.其他"); 40 root.add(leaf); 41 root.remove(leaf); 42 43 // 打印 44 root.display(1); 45 } 46 }
运行结果
+00.工作目录 +01.需求文档.doc +02.项目计划.xls +03.成员日报 +0301.李四的日报.doc +0302.王五的日报.doc +0303.张三日报目录 +01.张三日报_20200304.doc +02.张三日报_20200305.doc +04.验收报告.doc
三、总结
后续补充