定义
将对象组合成树形结构,以表示“整体-部分”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
本质
统一叶子对象和组合对象
登场角色
-
Leaf(叶子)
表示“内容”的角色,该角色中不能放入其他角色。
-
Composite(复合物)
表示“容器”的角色,可以在其中放入Leaf角色和Composite角色。
-
Component
使Leaf角色和Composite角色觉有一致性的角色,是叶子角色和复合物角色的父类。
-
Client
使用组合模式的角色。
示例代码
/**
* 表示文件和文件夹的抽象类
*
* 叶子角色和复合物角色的父类
*/
public abstract class Dir {
//声明一个List元素存储文件夹下的所有元素
protected List<Dir> dirs = new ArrayList<>();
private String name;//当前文件或者文件夹的名称
public Dir(String name) {
this.name = name;
}
//添加一个文件或者文件夹
public abstract void addDir(Dir dir);
//移除一个文件或者文件夹
public abstract void removeDir(Dir dir);
//清除文件夹下的所有元素
public abstract void clear();
//输入文件夹目录结构
public abstract void print();
//获取文件夹下所有的文件或者文件夹
public abstract List<Dir> getFiles();
//获取文件或者文件夹的名称
public String getName() {
return name;
}
}
/**
* 叶子角色
*/
public class File extends Dir{
public File(String name) {
super(name);
}
@Override
public void addDir(Dir dir) {
throw new UnsupportedOperationException("文件对象不支持该操作");
}
@Override
public void removeDir(Dir dir) {
throw new UnsupportedOperationException("文件对象不支持该操作");
}
@Override
public void clear() {
throw new UnsupportedOperationException("文件对象不支持该操作");
}
@Override
public void print() {
System.out.print(getName());
}
@Override
public List<Dir> getFiles() {
throw new UnsupportedOperationException("文件对象不支持该操作");
}
}
/**
* 复合角色
*/
public class Folder extends Dir{
public Folder(String name) {
super(name);
}
@Override
public void addDir(Dir dir) {
dirs.add(dir);
}
@Override
public void removeDir(Dir dir) {
dirs.remove(dir);
}
@Override
public void clear() {
dirs.clear();
}
@Override
public void print() {
System.out.print(getName() + "(");
Iterator<Dir> iterator = dirs.iterator();
while (iterator.hasNext()){
Dir dir = iterator.next();
dir.print();
if(iterator.hasNext()){
System.out.print(",");
}
}
System.out.print(")");
}
@Override
public List<Dir> getFiles() {
return dirs;
}
}
/**
* 测试,使用组合模式的角色
*/
public class Client {
public static void main(String[] args){
//构造一个目录对象表示C盘根目录
Dir diskC = new Folder("C盘");
//C盘根目录下有一个文件
diskC.addDir(new File("hello.txt"));
//C盘根目录下还有三个子目录
Dir windows = new Folder("Windows");
diskC.addDir(windows);
Dir logs = new Folder("Logs");
diskC.addDir(logs);
Dir users = new Folder("users");
diskC.addDir(users);
///Windows目录下添加文件
windows.addDir(new File("windows.txt"));
//Logs目录下添加文件
logs.addDir(new File("logs.txt"));
//Users目录下添加文件
users.addDir(new File("users.txt"));
diskC.print();
}
}
运行结果
C盘(hello.txt,Windows(windows.txt),Logs(logs.txt),users(users.txt))
功能
可以让使用者不用在区分叶子对象和组合对象,而是以一个统一的方式来调用。
优点
- 定义了包含基本对象和组合对象的类层次结构
- 统一了组合对象和叶子对象
- 简化了使用者的调用
- 更容易扩展,新定义的叶子对象和复合对象可以很容易的与已有结构兼容,而使用者不需要为了添加新的对象而改变。
缺点
很难限制组件中的组件类型。
何时使用
- 表示对象的“对象-整体”层次结构。
- 从一整体中能够独立出部分模块或者功能的场景。
网友评论