GOF23设计模式之组合模式(composite)

一、组合模式概述

  将对象组合成树状结构以表示“部分和整体”层次结构,使得客户可以统一的调用叶子对象和容器对象。

  (1)组合模式的使用场景

      把部分和整体的关系用树形结构来表示,从而使客户端可以使用统一的方式处理部分对象和整体对象。

  (2)组合模式核心

      抽象构件(Component)角色:定义了叶子和容器构件的共同点

      叶子(Leaf)构件角色:无子节点

      容器(Composite)构件角色:有容器特征,可以包含子节点

 1 /**
 2  * 抽象组件
 3  * @author CL
 4  *
 5  */
 6 public interface Component {
 7     void operation();
 8 }
 9 
10 /**
11  * 叶子组件
12  * @author CL
13  *
14  */
15 interface Leaf extends Component {
16 }
17 
18 /**
19  * 容器组件
20  * @author CL
21  *
22  */
23 interface Composite extends Component {
24     void add(Component c);
25     void remove(Component c);
26     Component getChild(int index);
27 }

二、组合模式工作流程分析

  (1)组合模式为处理树形结构提供了完美的解决方案,描述了如何将容器和叶子进行递归组合,使得用户在使用时可以一致性的对待容器和叶子。

  (2)当容器对象的指定方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员,并调用执行。其中,使用了递归调用的机制对整个结构进行处理。

三、使用组合模式模拟杀毒软件架构设计

  1 import java.util.ArrayList;
  2 import java.util.List;
  3 
  4 /**
  5  * 模拟杀毒软软件架构设计
  6  * 抽象组件
  7  * @author CL
  8  *
  9  */
 10 public interface AbstractFile {
 11     /**
 12      * 杀毒
 13      */
 14     void killVirus();
 15 }
 16 
 17 /**
 18  * 对图片文件进行杀毒
 19  * @author CL
 20  *
 21  */
 22 class ImageFile implements AbstractFile {
 23     private String name;
 24 
 25     public ImageFile(String name) {
 26         this.name = name;
 27     }
 28 
 29     @Override
 30     public void killVirus() {
 31         System.out.println("-->对图像文件\""+name+"\"进行查杀!");
 32     }
 33     
 34 }
 35 
 36 /**
 37  * 对文本文件进行杀毒
 38  * @author CL
 39  *
 40  */
 41 class TxtFile implements AbstractFile {
 42     private String name;
 43 
 44     public TxtFile(String name) {
 45         this.name = name;
 46     }
 47 
 48     @Override
 49     public void killVirus() {
 50         System.out.println("-->对文本文件\""+name+"\"进行查杀!");
 51     }
 52     
 53 }
 54 
 55 /**
 56  * 对视频文件进行杀毒
 57  * @author CL
 58  *
 59  */
 60 class VideoFile implements AbstractFile {
 61     private String name;
 62 
 63     public VideoFile(String name) {
 64         this.name = name;
 65     }
 66 
 67     @Override
 68     public void killVirus() {
 69         System.out.println("-->对视频文件\""+name+"\"进行查杀!");
 70     }
 71     
 72 }
 73 
 74 /**
 75  * 容器组件
 76  * @author CL
 77  *
 78  */
 79 class Folder implements AbstractFile {
 80     private String name;
 81     //容器:用来存放容器构建下的子节点
 82     private List<AbstractFile> list;
 83     
 84     public Folder() {
 85         list = new ArrayList<AbstractFile>();
 86     }
 87     
 88     public Folder(String name) {
 89         this();
 90         this.name = name;
 91     }
 92 
 93     public void add(AbstractFile file) {
 94         list.add(file);
 95     }
 96     
 97     public void remove(AbstractFile file) {
 98         list.remove(file);
 99     }
100     
101     public AbstractFile getChild(int index) {
102         return list.get(index);
103     }
104 
105     @Override
106     public void killVirus() {
107         System.out.println("-->文件夹\""+name+"\"进行查杀!");
108         
109         for (AbstractFile file : list) {
110             file.killVirus();    //递归
111         }
112     }
113     
114 }

  测试:

 1 /**
 2  * 使用组合模式模拟杀毒软件
 3  * @author CL
 4  *
 5  */
 6 public class Client {
 7 
 8     public static void main(String[] args) {
 9         //1. 将图片和文件加入到文件夹中,对文件夹进行查杀
10         Folder f1 = new Folder("我的文档");
11         AbstractFile f2, f3, f4, f5;
12         
13         f2 = new ImageFile("xaau.jpg");
14         f3 = new TxtFile("Hello.java");
15         f1.add(f2);
16         f1.add(f3);
17         
18         f1.killVirus();
19         
20         System.out.println("-----------------------------------");
21         
22         //2.在文件夹中再加入一个文件夹,其中包含两个视频文件
23         Folder f11 = new Folder("电影");
24         f4 = new VideoFile("宝贝计划.avi");
25         f5 = new VideoFile("泰囧.avi");
26         f11.add(f4);
27         f11.add(f5);
28         
29         f1.add(f11);
30         //对文件夹进行递归查杀
31         f1.killVirus();
32     }
33 }

  控制台输出:

-->文件夹"我的文档"进行查杀!
-->对图像文件"xaau.jpg"进行查杀!
-->对文本文件"Hello.java"进行查杀!
-----------------------------------
-->文件夹"我的文档"进行查杀!
-->对图像文件"xaau.jpg"进行查杀!
-->对文本文件"Hello.java"进行查杀!
-->文件夹"电影"进行查杀!
-->对视频文件"宝贝计划.avi"进行查杀!
-->对视频文件"泰囧.avi"进行查杀!

四、组合模式常用开发应用场景

  (1)操作系统的资源管理器;

  (2)GUI的容器层次图;

  (3)XML文件解析;

  (4)OA系统中,组织结构的处理;

  (5)Junit单元测试框架

      底层设计就是典型的组合模式,TestCase(叶子)、TestUnite(容器)、Test(抽象)

  (6)…………

posted @ 2018-01-22 09:57  C3Stones  阅读(358)  评论(0编辑  收藏  举报