使用组合模式的场景:把部分和整体的关系用树形结构来表示,从而使客户端可以使用统一的方式处理部分对象和整体对象。
组合模式核心:
抽象构件(Component)角色:定义了叶子和容器构件的共同点。
叶子(Leaf)构件角色:无子节点。
容器(Composite)构件角色:有容器特征,可以包含子节点。
组合模式工作流程分析:
组合模式为处理树形结构提供了完美的解决方案,描述了如何将容器和叶子进行递归组合,使得用户在使用时可以一致性的对待容器和叶子。
当容器对象的指定方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员,并调用执行。其中,使用了递归调用的机制对整个结构进行处理。
建立抽象组件接口Component,再建立叶子接口Leaf和容器接口Composite,二者都继承于Component
1 package com.ztq.composite; 2 3 /*** 4 * 抽象组件 5 * @author ZTQ 6 * 7 */ 8 public interface Component { 9 void opreation(); 10 } 11 12 //叶子组件 13 interface Leaf extends Component{ 14 15 } 16 17 //容器组件 18 interface Composite extends Component{ 19 void add(Component c); 20 void remove(); 21 Component getChild(int index); 22 }
例:
1. 创建AbstractFile接口,即相当于上面说的Component接口,建立多个类继承于此接口
1 package com.ztq.composite; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 //抽象构建 7 public interface AbstractFile { 8 void killVirus(); //杀毒 9 } 10 11 class ImageFile implements AbstractFile{ 12 private String name; 13 public ImageFile(String name){ 14 this.name = name; 15 } 16 @Override 17 public void killVirus() { 18 System.out.println("---图像文件:" + name + " ,进行查杀!"); 19 } 20 21 } 22 23 class TextFile implements AbstractFile{ 24 private String name; 25 public TextFile(String name){ 26 this.name = name; 27 } 28 @Override 29 public void killVirus() { 30 System.out.println("---文本文件:" + name + " ,进行查杀!"); 31 } 32 33 } 34 35 class VideoFile implements AbstractFile{ 36 private String name; 37 public VideoFile(String name){ 38 this.name = name; 39 } 40 @Override 41 public void killVirus() { 42 System.out.println("---视频文件:" + name + " ,进行查杀!"); 43 } 44 45 } 46 47 class Folder implements AbstractFile{ 48 private String name; 49 50 //定义容器,用来存放本容器构建下的子节点 51 private List<AbstractFile> list = new ArrayList<AbstractFile>(); 52 53 public Folder(String name){ 54 super(); 55 this.name = name; 56 } 57 58 public void add(AbstractFile file){ 59 list.add(file); 60 } 61 62 public void remove(AbstractFile file){ 63 list.remove(file); 64 } 65 66 public AbstractFile getChild(int index){ 67 return list.get(index); 68 } 69 70 @Override 71 public void killVirus() { 72 System.out.println("---文件夹:" + name + ",进行查杀"); 73 74 for(AbstractFile file : list){ 75 file.killVirus(); 76 } 77 } 78 79 }
3. 测试类Client
1 package com.ztq.composite; 2 3 public class Client { 4 public static void main(String[] args) { 5 Folder f1; 6 AbstractFile f2, f3, f4, f5, f6; 7 f1 = new Folder("我的收藏"); 8 f2 = new ImageFile("图像.jpg"); 9 f3 = new TextFile("Hello.txt"); 10 11 f1.add(f2); 12 f1.add(f3); 13 14 f1.killVirus(); 15 16 // f2.killVirus(); 17 } 18 }
结果
---文件夹:我的收藏,进行查杀 ---图像文件:图像.jpg ,进行查杀! ---文本文件:Hello.txt ,进行查杀!
开发中的应用场景:
操作系统的资源管理器
GUI中的容器层次图
XML文件解析
OA系统中,组织结构的处理
Junit单元测试框架
底层设计就是典型的组合模式,TestCase(叶子)、 TestUnite(容器)、Test接口(抽象)