设计模式-组合模式
一、定义
将对象组合成树形结构,以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
角色:
Component抽象构建角色:定义参加组合对象的共有方法和属性,可以定义一些默认行为或属性。
Leaf叶子构件:叶子对象,其下再也没有其他分支,依旧是遍历的最小单位。
Composite树枝构件:树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构。
合成模式的实现根据所实现接口的区别分为两种形式,分别称为安全式和透明式。
- 安全模式的合成模式要求管理聚集的方法只出现在树枝构件类中,而不出现在树叶构件类中。
- 透明式的合成模式要求所有的具体构件类,不论树枝构件还是树叶构件,均符合一个固定接口。
二、类型
结构型
三、适用场景
- 维护和战士部分-整体的场景,如树形菜单、文件和文件夹管理。
- 从一个整体中能够独立出部分模块或功能场景。
四、优点
- 高层模块调用简单:一颗树形结构中所有节点都是Component,局部和整体对调用者来说没有任何区别,高层模块不必关心自己处理的是单个对象还是整个组合结构。
- 节点自由增加:容易扩展,想要增加节点只要找到它的父节点就行,符合开闭原则,对后续的维护非常有利。
五、缺点
使得设计更加复杂。客户端需要花更多时间理清类之间的层次关系。
六、类图
透明:
安全:
七、代码实现
1)透明式:
Component抽象构建角色
package com.wms.structural.composite.open; public abstract class AbstractFile { private String name; public AbstractFile(String name) { this.name = name; } public String getName() { return name; } public abstract void add(AbstractFile abstractFile); public abstract void remove(AbstractFile abstractFile); public abstract void printFile(); }
Composite树枝构件
package com.wms.structural.composite.open; import java.util.ArrayList; import java.util.List; public class Folder extends AbstractFile { private List<AbstractFile> fileList = new ArrayList<AbstractFile>(); public Folder(String name) { super(name); } public void printFile() { System.out.println("folder:" + this.getName()); for (AbstractFile abstractFile : fileList) { abstractFile.printFile(); } } public void add(AbstractFile abstractFile) { fileList.add(abstractFile); } public void remove(AbstractFile abstractFile) { if (fileList.contains(abstractFile)) { fileList.remove(abstractFile); } } }
Leaf叶子构件
package com.wms.structural.composite.open; public class File extends AbstractFile { public File(String name) { super(name); } public void add(AbstractFile abstractFile) { throw new UnsupportedOperationException("文件不允许添加操作"); } public void remove(AbstractFile abstractFile) { throw new UnsupportedOperationException("文件不允许删除操作"); } public void printFile() { System.out.println("file:" + this.getName()); } }
测试类:
package com.wms.structural.composite.open; public class Test { public static void main(String[] args) { File txtFile = new File("txtFile"); File pdfFile = new File("pdfFile"); txtFile.add(pdfFile); File javaFile = new File("javaFile"); Folder rootFolder = new Folder("rootFolder"); Folder codeFolder = new Folder("codeFolder"); codeFolder.add(javaFile); Folder commonFolder = new Folder("commonFolder"); commonFolder.add(txtFile); commonFolder.add(pdfFile); rootFolder.add(codeFolder); rootFolder.add(commonFolder); rootFolder.printFile(); } }
2)安全式:
Component抽象构建角色
package com.wms.structural.composite.safe; public abstract class AbstractFile { private String name; public AbstractFile(String name) { this.name = name; } public String getName() { return name; } public abstract void printFile(); }
Composite树枝构件
package com.wms.structural.composite.safe; import java.util.ArrayList; import java.util.List; public class Folder extends AbstractFile { private List<AbstractFile> fileList = new ArrayList<AbstractFile>(); public Folder(String name) { super(name); } public void printFile() { System.out.println("folder:" + this.getName()); for (AbstractFile abstractFile : fileList) { abstractFile.printFile(); } } public void add(AbstractFile abstractFile) { fileList.add(abstractFile); } public void remove(AbstractFile abstractFile) { if (fileList.contains(abstractFile)) { fileList.remove(abstractFile); } } }
Leaf叶子构件
package com.wms.structural.composite.safe; public class File extends AbstractFile { public File(String name) { super(name); } public void printFile() { System.out.println("fileName:" + this.getName()); } }
测试类
package com.wms.structural.composite.safe; public class Test { public static void main(String[] args) { File txtFile = new File("txtFile"); File pdfFile = new File("pdfFile"); File javaFile = new File("javaFile"); Folder rootFolder = new Folder("rootFolder"); Folder codeFolder = new Folder("codeFolder"); codeFolder.add(javaFile); Folder commonFolder = new Folder("commonFolder"); commonFolder.add(txtFile); commonFolder.add(pdfFile); rootFolder.add(codeFolder); rootFolder.add(commonFolder); rootFolder.printFile(); } }