设计模式-组合模式

作者持续关注 WPS二次开发专题系列,持续为大家带来更多有价值的WPS开发技术细节,如果能够帮助到您,请帮忙来个一键三连,更多问题请联系我(QQ:250325397)

目录

定义

特点

使用场景

优缺点

[(1) 优点](#(1) 优点)

[(2) 缺点](#(2) 缺点)

模式结构

具体实现

实际应用


定义

组合(Composite Pattern)模式的定义:有时又叫作整体-部分(Part-Whole)模式,它是一种将对象组合成树状的层次结构的模式,用来表示"整体-部分"的关系,使用户对单个对象和组合对象具有一致的访问性,属于结构型设计模式。

组合模式一般用来描述整体与部分的关系,它将对象组织到树形结构中,顶层的节点被称为根节点,根节点下面可以包含树枝节点和叶子节点,树枝节点下面又可以包含树枝节点和叶子节点,树形结构图如下。

由上图可以看出,其实根节点和树枝节点本质上属于同一种数据类型,可以作为容器使用;而叶子节点与树枝节点在语义上不属于用一种类型。但是在组合模式中,会把树枝节点和叶子节点看作属于同一种数据类型(用统一接口定义),让它们具备一致行为。

特点

将对象组合成树形结构以表示"部分-整体"的层次结构。

使用场景

    • 在需要表示一个对象整体与部分的层次结构的场合,如树形菜单,文件、文件夹的管理。
    • 要求对用户隐藏组合对象与单个对象的不同,用户可以用统一的接口使用组合结构中的所有对象的场合。

优缺点

(1) 优点
    • 高层模块调用简单。
    • 节点自由增加。
(2) 缺点
    • 在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

模式结构

组合模式包含以下主要角色。

    • 抽象构件(Component)角色:它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。在透明式的组合模式中抽象构件还声明访问和管理子类的接口;在安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝构件完成。(总的抽象类或接口,定义一些通用的方法,比如新增、删除)
    • 树叶构件(Leaf)角色:是组合中的叶节点对象,它没有子节点,用于继承或实现抽象构件。
    • 树枝构件(Composite)角色 / 中间构件:是组合中的分支节点对象,它有子节点,用于继承和实现抽象构件。它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。

具体实现

具体实现类

复制代码
/**
 * 部门
 */
public class Department {
    /**
     * 编号
     */
    private String no;

    /**
     * 名称
     */
    private String name;

    /**
     * 级别
     */
    private int level;

    /**
     * 下级部门
     */
    private List<Department> subDepartments;

    public Department(String no, String name) {
        this.no = no;
        this.name = name;
        this.subDepartments = new ArrayList<>();
    }

    /**
     * 添加下级部门
     */
    public void add(Department department) {
        department.level = level + 1;
        subDepartments.add(department);
    }

    /**
     * 删除下级部门
     */
    public void remove(Department department) {
        subDepartments.remove(department);
    }

    /**
     * 获取下级部门列表
     */
    public List<Department> getSubDepartments() {
        return subDepartments;
    }

    @Override
    public String toString() {
        return "Department{" +
                "no='" + no + '\'' +
                ", name='" + name + '\'' +
                ", level=" + level +
                ", subDepartments=" + subDepartments +
                '}';
    }
}

具体使用

复制代码
public class App {
    public static void main(String[] args) {
        //公司
        Department company = new Department("000000", "xxx公司");

        //总裁办
        Department ceo = new Department("000001", "总裁办");
        company.add(ceo);

        //人力资源部
        Department hrCenter = new Department("000002", "人力资源部");
        ceo.add(hrCenter);

        //研发部
        Department rdCenter = new Department("000003", "研发部");
        ceo.add(rdCenter);

        //硬件研发部
        Department hardware = new Department("000004", "硬件研发部");
        rdCenter.add(hardware);

        //软件研发部
        Department software = new Department("000005", "软件研发部");
        rdCenter.add(software);

        System.out.println(company);

    }
}

实际应用

1、Android或者其他系统中的View、Window

2、文件系统

相关推荐
Zane199415 小时前
同一段单例代码,为什么在高并发下偶尔会创建出两个实例?聊聊哪种单例实现才是真的安全
设计模式
Carl_奕然15 小时前
【智能体】Loop 的四种设计模式之:Agent Loop(2026 最新版)
人工智能·设计模式·语言模型
小酒星小杜16 小时前
画 AI 漫画,别只会写“日漫风”:10 种画风、适用故事和可复制提示词
人工智能·设计模式·程序员
sarasuki1 天前
为什么 Agent 工具需要一个「协议」而不是「框架」:MCP 成为标准的底层逻辑
设计模式·agent·mcp
vivo互联网技术1 天前
知识不是文件,也不是向量 | KDC 系列 02
人工智能·设计模式·架构
Zane19947 天前
一个 new 就能创建对象,为什么还要拆出单例、工厂、建造者、原型四种模式?
设计模式
怕浪猫8 天前
一行命令复刻爆款视频,我把 Hypit 从安装跑到了出片
人工智能·设计模式·程序员
Zane19948 天前
函数式编程里的函数,其实不是你天天写的那个函数——三大编程范式的边界在哪
设计模式
Zane19949 天前
策略模式现在该不该上?一次讲清楚过度设计和设计不足怎么找平衡
设计模式
她说..9 天前
常见设计模式-模板方法模式
java·spring·设计模式·springboot