1.组合模式概述
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。(如文件系统中,可以把文件、文件夹当做同一类对象来操作,这正是组合模式的应用之处。) 组合模式依据树形结构来组合对象,(通俗点儿说,我认为就是在某一个类中有一个存放该类自身对象的集合,(比如:文件夹里面仍可以有文件夹,当然也可以有文件。))用来表示部分以及整体层次。
1.1模式意图:
将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
1.2.模式主要解决:
它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,(即操作统一)从而使得客户程序与复杂元素的内部结构解耦。
1.3.模式的结构
由此结构图可以看出,该模式有三个角色:
1.抽象构件角色(component),给参加组合的对象规定了一个接口,给出了共用的接口以及默认行为;
2.树叶构件角色(leaf)(联想文纪检系统中的文件),代表参加组合的树叶对象(树叶是没有下级子对象的) 他定义出了参加组合 的原始对象的行为;
3.树枝构件角色(composite),(联想文件系统的文件夹)代表参加组合的有子对象的对象,他给出但树枝构件对象的行为。
2.示例代码
通过示例代码,来了解各角色的作用。
import java.util.List;
/*
* 文件节点抽象(是文件和目录的父类) 即那个抽象构件角色
*/
public interface IFile {
/**
* 下面是一些默认行为
* @author:xnn
* 2018年11月26日下午10:22:38
*/
//显示文件或者文件夹的名称
public void display();
//添加、移除、获得子节点(虽然这些操作对于文件来说并不适用,但这里只是一个接口,我们可以在具体的实现类中加以控制:抛出异常、或者返回false都可以)
public boolean add(IFile file);
public boolean remove(IFile file);
public List<IFile> getChild();
}
import java.util.List;
/**
* 树叶构件角色
* 类(接口)描述:文件类 实现抽象构件角色的接口
* @author xnn
* 2018年11月26日下午10:27:32
*/
public class File implements IFile {
private String name;
public File(String name) {
this.name = name;
}
public void display() {
System.out.println(name);
}
//获取子对象,做返回null的处理
public List<IFile> getChild() {
return null;
}
/**
* 添加和移除都做返回fals的处理
*/
public boolean add(IFile file) {
return false;
}
public boolean remove(IFile file) {
return false;
}
}
import java.util.ArrayList;
import java.util.List;
/**
* 树枝构件角色
* 类(接口)描述:文件夹类
* @author xnn
* 2018年11月26日下午10:29:55
*/
public class Folder implements IFile{
private String name;
//一个文件夹下,可能有文件 也可能有文件夹,故泛型用他们的父类IFile
private List<IFile> children;
public Folder(String name) {
this.name = name;
children = new ArrayList<IFile>();
}
//显示
public void display() {
System.out.println(name);
}
//获取子对象
public List<IFile> getChild() {
return children;
}
//添加
public boolean add(IFile file) {
return children.add(file);
}
//移除
public boolean remove(IFile file) {
return children.remove(file);
}
}
import java.util.List;
public class MainClass {
public static void main(String[] args) {
//C盘
Folder rootFolder = new Folder("C:");
//教学视频目录
Folder subFolder = new Folder("教学视频");
//aaa.txt文件
File file = new File("aaa.txt");
rootFolder.add(subFolder);
rootFolder.add(file);
//语文目录
Folder subsubFolder = new Folder("语文");
File subFile = new File("11.avi");
subFolder.add(subsubFolder);
subFolder.add(subFile);
Folder subsubsubFolder = new Folder("虎穴");
File subsubFile = new File("问问.txt");
subsubFolder.add(subsubsubFolder);
subsubFolder.add(subsubFile);
displayTree(rootFolder,0);
}
public static void displayTree(IFile rootFolder, int deep) {
for(int i = 0; i < deep; i++) {
System.out.print("--");
}
//显示自身的名称
rootFolder.display();
//获得子树
List<IFile> children = rootFolder.getChild();
//遍历子树
for(IFile file : children) {
if(file instanceof File) {
for(int i = 0; i <= deep; i++) {
System.out.print("--");
}
file.display();
} else {
displayTree(file,deep + 1);
}
}
}
}
输出:
C:
--教学视频
----语文
------虎穴
------问问.txt
----11.avi
--aaa.txt
类图如下:
3.两种形式的组合模式