在这里插入图片描述

主页传送门:💁 传送

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.组合模式适用场景

组合模式适用于以下场景:

  1. 表示递归结构:组合模式适合用于表示树形或递归结构,例如文件系统、组织结构等,这些场景中需要对单个对象和组合对象进行一致处理。
  2. 客户端希望忽略差异:当客户端希望忽略组合对象与单个对象的差异时,可以使用组合模式,例如,客户端只需要对整个层次结构进行控制,而不关心具体的单个对象。
  3. 处理树形结构:组合模式适用于处理树形结构,需要对层次进行定义、忽略层次差异、简化客户端代码等。

总之,组合模式适用于处理树形结构或递归结构的场景,当客户端希望忽略差异、简化代码或符合开闭原则时,可以选择使用组合模式。同时需要注意其缺点,如设计复杂、不容易限制容器中的构件等。

6.组合模式总结

     组合模式是一种设计模式,旨在将对象组合成树形结构以表示“部分-整体”的层次结构。它允许客户端代码以一致的方式处理对象和对象容器,无需关心处理的单个对象还是组合的对象容器。
     总之,组合模式是一种有用的设计模式,可以在适当的情况下应用来简化客户端代码、降低耦合度和提高可扩展性。然而,它也有一些缺点和适用场景需要注意和考虑。

如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏 🙌一起讨论
你的支持就是我✍️创作的动力! 💞💞💞

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐