组合模式-

定义

组合模式最初只是用于解决树形结构的场景,更多的是处理对象组织结构之间的问题。而组合关系则是通过将不同对象封装起来完成一个统一功能

组合模式(composite pattern)的定义是:将对象组合成树形结构以表示整个部分的层次结构。组合模式可以让用户统一对待单个对象和对象的组合

结构图

案例演示

列出某一目录下所有的文件和文件夹

代码

/**
 * @Description: 抽象类(文件夹+文件)
 * @author: zhuoyue
 * @since: 2024/05/13 15:32
 */
public abstract class Entry {

    public abstract String getName();

    public abstract int getSize();

    /**
     * 添加文件或文件夹
     * @param entry
     * @return
     */
    public abstract Entry add(Entry entry);

    /**
     * 显示指定目录下的所有文件的信息
     * @param entry
     */
    public abstract void printList(String entry);


    @Override
    public String toString() {
        return getName()+"("+getSize()+")";
    }
}

public class File extends Entry{

    private String name;

    private int size;


    public File(String name, int size) {
        this.name = name;
        this.size = size;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public int getSize() {
        return size;
    }


    @Override
    public Entry add(Entry entry) {
        return null;
    }

    @Override
    public void printList(String entry) {
        System.out.println(entry+"/"+this);
    }

    public void setSize(int size) {
        this.size = size;
    }
}


public class Directory extends Entry{
    private String name;

    private ArrayList<Entry> directory = new ArrayList<>();

    public Directory(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return null;
    }

    @Override
    public int getSize() {
        int size = 0;
        for (Entry entry: directory){
            size += entry.getSize();
        }
        return size;
    }

    @Override
    public Entry add(Entry entry) {
        directory.add(entry);
        return this;
    }

    @Override
    public void printList(String prefix) {
        System.out.println(prefix+"/"+this);
        for (Entry entry: directory){
            entry.printList(prefix+"/"+name);
        }

    }
}


public class Client {

    public static void main(String[] args) {
        /**
         * 根节点
         */
        Directory rootDir = new Directory("root");

        /**
         * 树枝节点
         */
        Directory binDir = new Directory("bin");

        binDir.add(new File("vi",10000));
        binDir.add(new File("test",20000));

        Directory tmpDir = new Directory("tmp");

        Directory usrDir = new Directory("usr");
        Directory mysqlDir = new Directory("mysql");

        mysqlDir.add(new File("my.cnf",30));
        mysqlDir.add(new File("test.db",25000));
        usrDir.add(mysqlDir);

        rootDir.add(mysqlDir);

        rootDir.add(binDir);
        rootDir.add(tmpDir);
        rootDir.add(usrDir);

        rootDir.printList("");
    }
}

总结

组合模式分类

  • 透明组合模式

        在透明组合模式中,抽象根节点橘色中声明了所有用于管理成员对象的方法。

        缺点是不够安全,因为叶子对象和容器对象本质上还是有区别的,叶子对象不可能有下一个层次的对象,即不可能包含成员对象,因此为其提供add()、remove()等方法是没有意义的,这在编译阶段不会出错,但在运行阶段如果调用者这些方法可能会出错,(可以抛出异常)

  • 安全组合模式

        在抽象构件角色中不声明任何用于管理成员对象的方法,而是在树枝节点类中声明并实现这些方法。安全组合模式的缺点是不够透明,因为叶子构件和容器构件具有不同的方法,且容器构件中那些用于管理成员对象的方法没有在抽象构件中定义,因此客户端不能完全针对抽象编程,必须有区别的针对叶子构件和容器构件

  优点

  • 组件模式可以清楚的定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制。
  • 客户端可以一致的使用一个组合结构或其中单个对象,不必关心处理的结构是单个对象还是整个组织结构,简化了客户端代码。
  • 在组合模式中增加新的树枝节点或叶子节点都很方便,无须对现有类库进行任何修改,符合“开闭原则”
  • 组合模式为树形结构对象实现提供了一种灵活的解决方案,通过叶子节点和树枝节点的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单

缺点

  • 使用组合模式的前提在于你的业务场景是否能够表示成树形结构。所以组合模式的应用场景也比较局限,所以它并不是一种很常用的设计模式

应用场景

  • 处理一个树形结构,比如,公司人员组织架构、订单信息等
  • 跨越多个层次结构聚合数据,比如,统计文件夹下的文件总数
  • 统一处理一个结构中的多个对象,比如遍历文件夹下的所有XML类型文件内容

相关推荐

  1. 设计模式——组合模式

    2024-05-16 15:28:07       29 阅读
  2. 设计模式组合模式

    2024-05-16 15:28:07       16 阅读
  3. 【设计模式组合模式

    2024-05-16 15:28:07       13 阅读

最近更新

  1. DOM XMLHttpRequest

    2024-05-16 15:28:07       0 阅读
  2. nginx详解

    2024-05-16 15:28:07       0 阅读
  3. vue实现表单输入框数字类型校验功能

    2024-05-16 15:28:07       0 阅读
  4. Perl 语言入门学习

    2024-05-16 15:28:07       1 阅读
  5. perl语言入门学习

    2024-05-16 15:28:07       1 阅读
  6. Apache Spark 的基本概念和在大数据分析中的应用

    2024-05-16 15:28:07       1 阅读
  7. CSS 下拉菜单的设计与实现

    2024-05-16 15:28:07       1 阅读
  8. 快速排序算法Python实现

    2024-05-16 15:28:07       1 阅读
  9. python爬虫入门(二)之Requests库

    2024-05-16 15:28:07       1 阅读

热门阅读

  1. 【深度学习】Pytorch模型转成Onnx

    2024-05-16 15:28:07       16 阅读
  2. 6 使用 AspectJ 的 AOP 配置管理事务

    2024-05-16 15:28:07       13 阅读
  3. 自定义一个starter

    2024-05-16 15:28:07       13 阅读
  4. ESP32 Arduino 定时器中断

    2024-05-16 15:28:07       14 阅读
  5. vue3-响应式API(工具函数)-unRef

    2024-05-16 15:28:07       13 阅读
  6. 【数据库】高并发场景下的数据库开发注意要点

    2024-05-16 15:28:07       14 阅读