文章目录
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/1ad512ad7ed780b2cb7c3b15f2aadd1e.png)
主页传送门:💁 传送
1.组合模式定义
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
Compose objects into tree structure to represent part-whole hierarchies.Composite lets client treat individual objects and compositions of objects uniformly.
即:将对象组合成树形结构以表示 “部分-整体” 的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
2.组合模式的结构
组合模式的实现根据所实现接口的区别分为两种形式,分别称为安全式和透明式。
2.1. 安全式组合模式的结构
安全模式的组合模式要求管理聚集的方法只出现在树枝构件类中,而不出现在树叶构件类中。
这种形式涉及到三个角色:
-
抽象构件(Component)角色: 这是一个抽象角色,它给参加组合的对象定义出公共的接口及其默认行为,可以用来管理所有的子对象。合成对象通常把它所包含的子对象当做类型为Component的对象。在安全式的组合模式里,构件角色并不定义出管理子对象的方法,这一定义由树枝构件对象给出。
-
树叶构件(Leaf)角色: 树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为。
-
树枝构件(Composite)角色: 代表参加组合的有下级子对象的对象。树枝构件类给出所有的管理子对象的方法,如add()、remove()以及getChild()。
安全式组合模式的缺点是不够透明,因为树叶类和树枝类将具有不同的接口。
2.2.透明式组合模式的结构
与安全式的组合模式不同的是,透明式的组合模式要求所有的具体构件类,不论树枝构件还是树叶构件,均符合一个固定接口。
3.组合模式实战案例
3.1.场景说明
设计一个文件系统的杀毒软件,文件系统可以分为文件夹和文件,文件又分为文本文件,图片文件,视频文件。
3.2.关系类图
使用组合模式来实现的结构图如下:
3.3.代码实现
//Component 抽象构件
/**
* 抽象文件类:抽象构件接口
*/
interface File {
/**
* 默认方法
* @param file
*/
public default void add(File file) {
throw new RuntimeException("reject");
}
public default void remove(File file) {
throw new RuntimeException("reject");
}
public default File getChild(int index) {
throw new RuntimeException("reject");
}
void killVirus();
}
//Leaf 叶子构件
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 图像文件类:叶子构建
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
class ImageFile implements File {
private String name;
@Override
public void killVirus() {
System.out.println("---对图像文件:" + name + "正在杀毒!");
}
}
/**
* 文本文件类:叶子构件
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
class TextFile implements File {
private String name;
@Override
public void killVirus() {
System.out.println("---对文本文件:" + name + "正在杀毒!");
}
}
/**
* 视频文件类:叶子构建
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
class VideoFile implements File {
private String name;
@Override
public void killVirus() {
System.out.println("---对视频文件:" + name + "正在杀毒!");
}
}
//Composite 容器构件
import java.util.ArrayList;
import java.util.List;
/**
* 文件夹类:容器构件
*/
class Folder implements File {
/**
* 存储File类型的成员
*/
private List<File> fileList = new ArrayList<>();
private String name;
public Folder(String name) {
this.name = name;
}
@Override
public void add(File file) {
this.fileList.add(file);
}
@Override
public void remove(File file) {
this.fileList.remove(file);
}
@Override
public File getChild(int index) {
return this.fileList.get(index);
}
@Override
public void killVirus() {
System.out.println("---对文件夹:" + name + "进行杀毒!");
for (File file : fileList) {
file.killVirus();
}
}
}
// 场景类
/**
* 组合模式案例
* @author Liucheng
* @since 2019-07-26
*/
public class Client {
public static void main(String[] args) {
File folder1 = new Folder("Sunny的资料");
File folder2 = new Folder("图像文件");
File folder3 = new Folder("文本文件");
File folder4 = new Folder("视频文件");
File file1 = new ImageFile("小龙女.jpg");
File file2 = new ImageFile("张无忌.gif");
File file3 = new TextFile("九阴真经.txt");
File file4 = new TextFile("葵花宝典.doc");
File file5 = new VideoFile("笑傲江湖.rmvb");
folder2.add(file1);
folder2.add(file2);
folder3.add(file3);
folder3.add(file4);
folder4.add(file5);
folder1.add(folder2);
folder1.add(folder3);
folder1.add(folder4);
//从“Sunny的资料”节点开始进行杀毒操作
folder1.killVirus();
}
}
4.组合模式优缺点
组合模式是一种结构型设计模式,它允许将对象组合成树状的层次结构,以表示“整体-部分”的关系。组合模式的优点和缺点如下:
优点:
- 简化客户端代码:组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象还是组合对象,这简化了客户端代码。
- 更容易添加新对象:在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,这符合“开闭原则”。
缺点:
- 设计较复杂:客户端需要花更多时间理清类之间的层次关系。
- 不容易限制容器中的构件:不容易用继承的方法来增加构件的新功能。
5.组合模式适用场景
组合模式适用于以下场景:
- 表示递归结构:组合模式适合用于表示树形或递归结构,例如文件系统、组织结构等,这些场景中需要对单个对象和组合对象进行一致处理。
- 客户端希望忽略差异:当客户端希望忽略组合对象与单个对象的差异时,可以使用组合模式,例如,客户端只需要对整个层次结构进行控制,而不关心具体的单个对象。
- 处理树形结构:组合模式适用于处理树形结构,需要对层次进行定义、忽略层次差异、简化客户端代码等。
总之,组合模式适用于处理树形结构或递归结构的场景,当客户端希望忽略差异、简化代码或符合开闭原则时,可以选择使用组合模式。同时需要注意其缺点,如设计复杂、不容易限制容器中的构件等。
6.组合模式总结
组合模式是一种设计模式,旨在将对象组合成树形结构以表示“部分-整体”的层次结构。它允许客户端代码以一致的方式处理对象和对象容器,无需关心处理的单个对象还是组合的对象容器。
总之,组合模式是一种有用的设计模式,可以在适当的情况下应用来简化客户端代码、降低耦合度和提高可扩展性。然而,它也有一些缺点和适用场景需要注意和考虑。
如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏 🙌一起讨论
你的支持就是我✍️创作的动力! 💞💞💞