大聪明教你学Java设计模式 | 第十篇:组合模式

5,422 阅读5分钟

前言

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第15天,点击查看活动详情

🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。

🍊支持作者: 点赞👍、关注💖、留言💌~ 大聪明在写代码的过程中发现设计模式的影子是无处不在,设计模式也是软件开发人员在软件开发过程中面临的一般问题的解决方案。大聪明本着“独乐乐不如众乐乐”的宗旨与大家分享一下设计模式的学习心得。

组合模式

🍓🍓什么是组合模式🍓🍓

在讲解组合模式之前,我们先来看一下它的定义👇

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

我们还是通过一个小例子来帮助我们理解组合模式的意义:我们的电脑中都有文件资源管理器(就是文件夹😂),文件资源管理器由目录和具体的文件组成,每个目录下都拥有属于自己的文件或者子目录,每个文件里又装着属于自己的内容。那么目录就相当于是由单个对象(即具体文件)或组合对象(即子目录)构成的,如果在开发应用软件时需要描述类似这样的树形数据结构,那么就可以选择使用组合模式。

组合模式在我们处理树型结构的问题时,帮助我们模糊了简单元素和复杂元素的概念,也就是将对象组合成树形结构来表示“部分-整体”的层次结构,那么程序可以像处理简单元素一样来处理复杂元素(也就是对单个对象和组合对象的操作具有一致性),从而使得程序与复杂元素的内部结构之间达到解耦。

🍓🍓组合模式的实现🍓🍓

我们再说一个和我们息息相关的小例子,每一位小伙伴所在的公司都有很多同事,他们有的是领导,有的是普通的员工,无论是领导还是员工都有自己的上级或下级(当然了,董事长这种大BOSS就没有上级了😂)。接下来我们就用代码来简单实现一下这个例子👇

🍎创建一个员工类🍎

import java.util.ArrayList;
import java.util.List;

/**
 * 员工类
 * @description: Employee
 * @author: 庄霸.liziye
 * @create: 2022-04-10 21:49
 **/
public class Employee {
    /**
     * 员工姓名
     */
    private String name;

    /**
     * 员工岗位
     */
    private String post;

    /**
     * 下级员工
     */
    private List<Employee> subordinates;

    /**
     * 构造方法
     */
    public Employee(String name,String post) {
        this.name = name;
        this.post = post;
        subordinates = new ArrayList<Employee>();
    }

    public void add(Employee e) {
        subordinates.add(e);
    }

    public void remove(Employee e) {
        subordinates.remove(e);
    }

    public List<Employee> getSubordinates(){
        return subordinates;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", post='" + post + '\'' +
                ", subordinates=" + subordinates +
                '}';
    }
}

🍎通过员工类来创建并打印员工的层次结构🍎

/**
 * @description: Test
 * @author: 庄霸.liziye
 * @create: 2022-04-10 22:03
 **/
public class Test {
    public static void main(String[] args) {
        Employee CEO = new Employee("张三","董事长");

        Employee leader1 = new Employee("李四","研发主管");

        Employee leader2 = new Employee("王五","销售总管");

        Employee programmer1 = new Employee("小明","Java程序员");
        Employee programmer2 = new Employee("小刚","C++程序员");

        Employee sales1 = new Employee("小红","销售");
        Employee sales2 = new Employee("小芳","销售");

        CEO.add(leader1);
        CEO.add(leader2);

        leader1.add(programmer1);
        leader1.add(programmer2);

        leader2.add(sales1);
        leader2.add(sales2);

        //打印该组织的所有员工
        System.out.println(CEO);
        for (Employee headEmployee : CEO.getSubordinates()) {
            System.out.println(headEmployee);
            for (Employee employee : headEmployee.getSubordinates()) {
                System.out.println(employee);
            }
        }
    }
}

在这里插入图片描述

🍓🍓组合模式的优、缺点🍓🍓

最后我们总结一下组合模式的优点与缺点👇

🍌🍌优点🍌🍌

高层模块(就像上面代码中的CEO)调用简单。组合模式让客户端(即 main 方法)代码可以一致的处理单个对象和组合对象,并不需要再耗费精力去关心自己处理的是单个对象还是组合对象,这也就帮助我们简化了客户端代码;同时节点可以自由增加,更容易在组合体内加入新的对象,客户端也不会因为加入了新的对象而更改源代码,满足了“开闭原则”;

🍌🍌缺点🍌🍌

在使用组合模式时,节点和其子节点的声明都是实现类,而不是接口去声明,这也违反了依赖倒置原则;而且使用组合模式会导致代码设计变得更复杂,客户端需要花更多时间去梳理类之间的层次关系;

小结

本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨🙇‍

希望各位小伙伴动动自己可爱的小手,来一波点赞+关注 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●'◡'●)

如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。

爱你所爱 行你所行 听从你心 无问东西