设计模式-组合模式

核心思想

  • 组合模式可以使用一棵树来表示
  • 组合模式使得用户可以使用一致的方法操作单个对象和组合对象
  • 组合模式又叫部分整体模式,将对象组合成树形结构以表示"部分-整体"的层次结构,可以更好的实现管理操作,部分-整体对象的操作基本一样,但是应该还会有不一样的地方

场景使用

  • 比如文件夹和文件,都有增加、删除等api,也有层级管理关系
  • 比如公司,总公司下有子公司,每个公司的部门都类似

优缺点

优点

  • 方便创建出复杂的层次结构
  • 客户端只需要面对一致的对象而不用考虑整体部分的问题

缺点

  • 需要花更多的时间理清类之间的层次关系

代码示例

根节点(抽象类-Component)

java 复制代码
public abstract class Root {

    private String name;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public abstract void addFile(Root root);

    public abstract void removeFile(Root root);

    public abstract void display(int depth);

}

具体文件夹类(Composite)

java 复制代码
public class Folder extends Root {

    private List<Root> folders = new ArrayList<>();


    public Folder(String name) {
        super(name);
    }

    public List<Root> getFolders() {
        return folders;
    }

    public void setFolders(List<Root> folders) {
        this.folders = folders;
    }

    @Override
    public void addFile(Root root) {
        folders.add(root);
    }

    @Override
    public void removeFile(Root root) {
        folders.remove(root);
    }

    @Override
    public void display(int depth) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        //打印横线和当前文件名
        System.out.println(sb.toString() + this.getName());

        for (Root r : folders) {
            //每个下级
            r.display(depth + 1);
        }
    }
}

具体的文件(Leaf)

java 复制代码
public class File extends Root {


    public File(String name) {
        super(name);
    }

    @Override
    public void addFile(Root root) {

    }

    @Override
    public void removeFile(Root root) {

    }

    @Override
    public void display(int depth) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        //打印横线和当前文件名
        System.out.println(sb.toString() + this.getName());

    }
}

测试

java 复制代码
public class AppRun {
    public static void main(String[] args) {

        //创造根⽂件夹
        Root root1 = new Folder("root");

        //建⽴⼦⽂件
        Root comp1 = new Folder("Composite1");
        Root comp2 = new Folder("Composite2");

        //建⽴⽂件夹关系
        root1.addFile(comp1);
        root1.addFile(comp2);

        //建⽴⽂件关系
        comp1.addFile(new File("leafA"));
        comp2.addFile(new File("leafB"));

        //展示
        root1.display(1);
    }
}
相关推荐
SimonKing3 分钟前
想搭建知识库?Dify、MaxKB、Pandawiki 到底哪家强?
java·后端·程序员
程序员清风10 分钟前
为什么Tomcat可以把线程数设置为200,而不是2N?
java·后端·面试
用户03321266636717 分钟前
掌控演示文稿视觉:Java 如何为 PowerPoint 设置背景
java
布朗克16819 分钟前
OpenTelemetry 在 Spring Boot 项目中的3种集成方式
java·开发语言·opentelemetry
拾荒的小海螺24 分钟前
JAVA:Nginx 事件驱动模型的技术指南
java·网络·nginx
MrSYJ27 分钟前
nimbus-jose-jwt你都会吗?
java·后端·微服务
渣哥35 分钟前
很多人只会写 Java,却从未真正理解字节码!
java
用户27079129381840 分钟前
JDK 7 和 JDK 8 中的 HashMap 有什么不同?
java·后端
程序员小富43 分钟前
令牌桶VS漏桶:谁才是流量控制的“最优解”?
java·后端·算法