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)…………