设计模式之组合模式

一、介绍

组合模式(Composite Pattern),属于结构型设计模式。组合模式常用于树形的数据结构,比如:多级菜单、部门层级关系、html文本中的dom树。它的特点是使用户对单个对象和组合对象的使用是相同的,也就是说,使用组合模式可以把一个子节点与其父节点统一处理。当我们对一个节点按照某种逻辑进行处理时,与此同时,会以类似递归的形式对其子节点按照相同的逻辑进行处理。

该设计模式主要角色就两种:①抽象接口,②实现类

二、组合模式中的角色

  • 抽象类 Component(抽象构件)

    在组合模式中,由于类与类之间的结构是树形结构(即上下级关系),因此我们可以对这些类进行无差别地抽象出一个接口类,用于定义各个类的行为,在适当情况下实现所有类共有接口的默认行为。

  • 实现类 Leaf(叶子构件)

    抽象类中定义了行为,因此我们可以对该抽象类定义不同的子类,对该行为实现不同的逻辑

  • 组合类 (组合构件)

    对不同的实现类进行实例化后,按照树形的结构对其进行组合。当对一个节点调用抽象类定义的方法时,按照类似递归的方式,也对其所有子孙节点进行调用。以实现对父节点和子节点的统一处理。定义有子部件的那些部件的行为,存储子部件,在Component接口中实现与子部件有关的操作。

三、核心思想

  • 统一接口:叶子节点和组合节点使用相同的接口
  • 递归结构:支持树形结构的递归操作
  • 透明性:客户端无需区分叶子节点和组合节点
  • 整体-部分:将部分对象组合成整体对象

四、案例一

我们以公司员工为例 ,不同的员工可向下管理多个员工,而每一个员工都有一个共同的动作:领工资

java 复制代码
public interface Employ {

    /**
     * 领工资
     */
    void getSalary();

    /**
     * 添加员工
     */
    void addEmployee(Employ employ);

    /**
     * 获取当前员工可管理的员工
     */
    List<Employ> children();
}

添加员工实现类(EmployImpl):

java 复制代码
public class EmployImpl implements Employ{
   // 员工姓名
    private String name;
    // 员工工资
    private String salary;
    // 可管理的员工集合
    private List<Employ> employList = new ArrayList<>();

    // 通过姓名和薪资实例化一个员工
    public EmployImpl(String name, String salary) {
        this.name = name;
        this.salary = salary;
    }

    // 领工资
    @Override
    public void getSalary() {
        System.out.println("员工姓名:" + name + ",领取工资:" + salary);
        // 管理的员工集合也领工资
        for (Employ employ : employList) {
            employ.getSalary();
        }
    }

    // 添加一个员工
    @Override
    public void addEmployee(Employ employ) {
        employList.add(employ);
    }

    // 获取管理的员工集合
    @Override
    public List<Employ> children() {
        return employList;
    }

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

测试

五、案例二

Component(抽象构件)

java 复制代码
// 抽象组件
public abstract  class Node {
    // 抽象的组件对象,为组合中的对象声明接口,实现接口的缺省行为
    abstract public void p();

}

Leaf(叶子构件)

java 复制代码
public class LeafNode extends Node {
    String name;

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

    @Override
    public void p() {
        System.out.println(name);
    }

}

Composite(组合构件)

java 复制代码
public class BranchNode extends Node{
    List<Node> nodes = new ArrayList<>();
    String name;

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

    public void add(Node n) {
        nodes.add(n);
    }
    @Override
    public void p() {
        System.out.println(name);
    }

}

客户调用

java 复制代码
public class Test {
    public static void main(String[] args) {
        BranchNode root = new BranchNode("root");
        BranchNode chapter1 = new BranchNode("chapter1");
        BranchNode chapter2 = new BranchNode("chapter2");
        Node chapter3 = new LeafNode("chapter3");
        Node c11 = new LeafNode("c31");
        Node c12 = new LeafNode("c32");
        BranchNode b21 = new BranchNode("section21");
        Node c211 = new LeafNode("c211");
        Node c212 = new LeafNode("c212");
        root.add(chapter1);
        root.add(chapter2);
        root.add(chapter3);
        chapter1.add(c11);
        chapter1.add(c12);
        chapter2.add(b21);
        b21.add(c211);
        b21.add(c212);
        tree(root, 0);
    }
    static void tree(Node b, int depth) {
        for(int i=0; i<depth; i++) System.out.print("--");
        b.p();

        if(b instanceof BranchNode) {
            for (Node n : ((BranchNode)b).nodes) {
                tree(n, depth + 1);
            }
        }
    }
}

输出

六、优缺点

核心优势
  • 统一接口:叶子节点和组合节点使用相同接口
  • 递归结构:支持树形结构的递归操作
  • 透明性:客户端无需区分叶子节点和组合节点
  • 扩展性:易于添加新的叶子节点和组合节点
注意事项
  • 性能考虑:深层递归可能影响性能
  • 内存管理:复杂结构需要注意内存泄漏
  • 设计复杂度:增加了系统的复杂度
  • 类型安全:透明式模式可能产生运行时异常

七、总结

组合模式是一种重要的结构型设计模式,它通过将对象组合成树形结构,实现了部分-整体的层次结构,并提供了统一的接口

相关推荐
callJJ2 小时前
Spring设计模式与依赖注入详解
java·spring·设计模式·idea·工厂模式
ExiFengs2 小时前
Java使用策略模式实现多实体通用操作的优雅设计
java·开发语言·设计模式·策略模式
茶本无香2 小时前
设计模式之三—工厂模式:灵活对象创建的艺术
java·开发语言·设计模式·工厂模式
Yu_Lijing4 小时前
基于C++的《Head First设计模式》笔记——命令模式
c++·笔记·设计模式
天“码”行空4 小时前
java的设计模式-----------单例类
java·开发语言·设计模式
一条闲鱼_mytube4 小时前
智能体设计模式 - 核心精华
人工智能·设计模式
Engineer邓祥浩4 小时前
设计模式学习(11) 23-9 组合模式
学习·设计模式·组合模式
Engineer邓祥浩4 小时前
设计模式学习(13) 23-11 享元模式
学习·设计模式·享元模式
刀法如飞16 小时前
开箱即用的 DDD(领域驱动设计)工程脚手架,基于 Spring Boot 4.0.1 和 Java 21
java·spring boot·mysql·spring·设计模式·intellij-idea