设计模式--结构模式--组合模式

一、基本概念

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 }
View Code

  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 }
View Code

  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 }
View Code

  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 }
View Code

运行结果

+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 }
View Code

  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 }
View Code

  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 }
View Code

  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 }
View Code

运行结果

+00.工作目录
 +01.需求文档.doc
 +02.项目计划.xls
 +03.成员日报
  +0301.李四的日报.doc
  +0302.王五的日报.doc
  +0303.张三日报目录
   +01.张三日报_20200304.doc
   +02.张三日报_20200305.doc
 +04.验收报告.doc
View Code

三、总结

       后续补充

猜你喜欢

转载自www.cnblogs.com/fating/p/12549793.html
今日推荐