使用组合模式的场景:把部分和整体的关系用树形结构来表示,从而使客户端可以使用统一的方式处理部分对象和整体对象。
组合模式核心:
抽象构件(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 @Override17 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 @Override29 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 @Override41 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 Listlist = new ArrayList ();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 @Override71 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接口(抽象)