组合模式 合成模式 COMPOSITE 结构型 设计模式(十一)
组合模式(合成模式 COMPOSITE)
参与组合对象的单个对象,也就是定义了参加组合对象的原始根本对象的行为
叶子节点下没有下级对象 Composite组合对象角色 也就是树枝角色,单个对象组合起来的一个对象,由多个单一对象构成 并且给出组合对象的行为(实现Component约定的行为) Client客户端角色 给单个对象或者组合对象施加命令,也就是调用Component中的方法,比如删除行为保存
File的delete方法直接删除,Folder则会便利内部的List 逐个删除
意图
将对象组合成树形结构以表示“部分-整体”的层次结构。 Composite使得用户对单个对象和组合对象的使用具有一致性。树形结构介绍
为了便于理解,我们先介绍一下树形结构 什么是树形结构? windows系统的文件夹树形结构,部门组织架构,行政区...都是一种树形结构 对于最终的节点,称之为叶子;否则是树枝 对于树形结构经常会有一种使用场景:对他们下发一致性的指令 比如:对于操作系统有删除操作,即可以删除一个文件,也可以删除一个文件夹,包括他下面所有的文件 类似删除操作这种命令,并不关心这到底是一个文件(叶子)还是一个文件夹(树枝),关心在意的只是要删除目标 但是对于不同的类型,文件(叶子)还是 文件夹(树枝),他们的处理又的确是不同的 文件只需要删除就可以了,文件夹还需要递归遍历内部的文件夹,直至所有的叶子节点,并且将他们全部删除 这就出现了一个矛盾 客户端其实并不关心到底是叶子还是树枝 但是他却不得不“关心”,因为他需要分情况处理 客户端当然希望不关注目标的具体类型,也就是希望能够:满足依赖倒置原则,不关注具体类型,面向抽象进行编程 最简单的方法就是将叶子和树枝抽象出来一种新的类型组件 如此一来,删除操作仅仅关心组件类型,不在关注到底是叶子还是树枝 组件提供统一的协议约定,叶子和树枝共同实现,将它们的不同点的细节封装到他们内部的方法中 这就能够让用户“单个对象和组合对象的使用具有一致性”。 所以,组合模式就是对于树形结构场景下的一种使用模式 共同的抽象提取为新的组件Component,可以表示叶子或者树枝 但是需要注意到:树枝可以有多个树叶组成,树枝上面也可能是树枝,也就是说,作为树枝的节点,也会包含Component 所以完整的结构图为: 所以组合模式的意图,从结构图中的Component中就可以看出来 他们都是Component,所以具有一致性。 借助于Composite与Component的关系,又能够表述整体与部分的关系。结构
Component 抽象构建角色 根据单个对象和组合对象的特点,规定的一个抽象角色(接口或抽象类),定义了共同的行为 或者说将"整体"和"部分"提取共性,进行抽象提取。 Leaf 叶子角色参与组合对象的单个对象,也就是定义了参加组合对象的原始根本对象的行为
叶子节点下没有下级对象 Composite组合对象角色 也就是树枝角色,单个对象组合起来的一个对象,由多个单一对象构成 并且给出组合对象的行为(实现Component约定的行为) Client客户端角色 给单个对象或者组合对象施加命令,也就是调用Component中的方法,比如删除行为
示例代码
以删除文件为例 FileSystem文件系统类 拥有删除方法delete() 他有两个实现类文件 File 和文件夹Folder Folder中可以有文件和文件夹,使用内部的Listpackage composite; public interface FileSystem { void delete(); }
package composite; public class File implements FileSystem { @Override public void delete() { System.out.println("delete file..."); } }
package composite; import java.util.ArrayList; import java.util.List; public class Folder implements FileSystem { List客户端fileSystemList = new ArrayList<>(); @Override public void delete() { for(FileSystem fileSystem:fileSystemList){ fileSystem.delete(); } } public void add(FileSystem fileSystem){ fileSystemList.add(fileSystem); } }
package composite; public class Client { public static void del(FileSystem fileSystem){ fileSystem.delete(); System.out.println("DELETED"); System.out.println(); } public static void main(String[] args){ Folder folder = new Folder(); Folder folder1 = new Folder(); Folder folder2 = new Folder(); Folder folder3 = new Folder(); File file1 = new File(); File file2 = new File(); File file3 = new File(); File file4 = new File(); folder.add(file1); folder.add(folder1); folder.add(folder2); folder1.add(file2); folder1.add(folder3); folder3.add(file4); folder2.add(file3); del(folder); del(folder1); del(file2); del(folder2); } }
del(folder);
del(folder1);
del(file2);
del(folder2);
在示例代码中,借助于FileSystem这一抽象的组件Componet 将File 这一Leaf角色和 Folder 这一Composite角色 组织成 “部分--整体”的树形结构 并且,对于客户端提供统一的外在形式----Component 使得客户端对单个对象和组合对象的使用具有一致性 这就是组合模式的运用