• Java特性之设计模式【组合模式】


    一、组合模式

    概述

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

    这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式

    主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦

    何时使用:1、想表示对象的部分-整体层次结构(树形结构) 2、希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象

    优缺点

    优点:

    • 组合模式通过递归的形式遍历组合对象,使得对象可以无限层次地嵌套。这样可以更加灵活地表示复杂的结构,并能够方便地对整个结构进行操作
    • 通过组合模式,以统一的方式处理整体和部分,不需要关心当前操作的对象是叶节点还是组合节点,可以统一地进行操作

    缺点:

    • 在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则

    1. 各个角色介绍

    1.1 组件(Component)

    • 定义了组合中所有对象的通用接口,可以是抽象类或接口。它声明了用于访问和管理子组件的方法,包括添加、删除、获取子组件等

    1.2 叶子节点(Leaf)

    • 表示组合中的叶子节点对象,叶子节点没有子节点。它实现了组件接口的方法,但通常不包含子组件

    1.3 复合节点(Composite)

    • 表示组合中的复合对象,复合节点可以包含子节点,可以是叶子节点,也可以是其他复合节点。它实现了组件接口的方法,包括管理子组件的方法

    2. UML图

    ​ 我们有一个类 Component 对象作为所有对象的通用接口,然后 LeafComposite 分别实现该接口,并通过 Composite 构建非叶子节点和叶子节点,形成树状图,并以中序遍历的形式输出

    在这里插入图片描述

    3. 具体例子和代码

    角色分配

    • Component:抽象组件
    • Leaf:叶子节点(叶子节点下,无组件,继承Component)
    • Composite:组合节点(继承Component)

    3.1 抽象组件

    • Component
    package com.vinjcent.prototype.composite;
    
    import io.swagger.annotations.ApiModelProperty;
    
    /**
     * @author vinjcent
     * @description 抽象组件
     * @since 2024/3/11 22:16
     */
    public abstract class Component {
    
        @ApiModelProperty("组件名称")
        protected String name;
    
        public Component(String name) {
            this.name = name;
        }
    
        /**
         * 组件操作
         */
        public abstract void operation();
    
        /**
         * 为当前组件添加组件
         *
         * @param component 需要添加的组件
         */
        public abstract void add(Component component);
    
        /**
         * 移除某一组件
         *
         * @param component 需要移除的组件
         */
        public abstract void remove(Component component);
    
        /**
         * 根据下标获取子组件
         *
         * @param index 下标
         * @return 下标对应组件
         */
        public abstract Component getChild(int index);
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    3.2 叶子节点

    • Leaf
    package com.vinjcent.prototype.composite;
    
    /**
     * @author vinjcent
     * @description 叶子节点(叶子节点下,无组件)
     * @since 2024/3/11 22:20
     */
    public class Leaf extends Component {
    
        public Leaf(String name) {
            super(name);
        }
    
        public void operation() {
            System.out.println("Leaf " + name + " is performing operation.");
        }
    
        public void add(Component component) {
            // 在叶节点中无法添加子节点,可以选择抛出异常或忽略该操作
            throw new UnsupportedOperationException("Unsupported operation: add");
        }
    
        public void remove(Component component) {
            // 在叶节点中无法移除子节点,可以选择抛出异常或忽略该操作
            throw new UnsupportedOperationException("Unsupported operation: remove");
        }
    
        public Component getChild(int index) {
            // 叶节点没有子节点,返回null或抛出异常
            return null;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    3.3 组合节点

    • Composite
    package com.vinjcent.prototype.composite;
    
    import io.swagger.annotations.ApiModelProperty;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author vinjcent
     * @description 组合节点
     * @since 2024/3/11 22:44
     */
    public class Composite extends Component {
    
        @ApiModelProperty("子节点")
        private List<Component> children;
    
        public Composite(String name) {
            super(name);
            children = new ArrayList<>();
        }
    
        @Override
        public void operation() {
    
            System.out.println("Composite " + name + " is performing operation.");
            for (Component child : children) {
                child.operation();
            }
    
        }
    
        @Override
        public void add(Component component) {
            children.add(component);
        }
    
        @Override
        public void remove(Component component) {
            children.remove(component);
        }
    
        @Override
        public Component getChild(int index) {
            return children.get(index);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    3.4 测试主函数

    package com.vinjcent.prototype.composite;
    
    /**
     * @author vinjcent
     * @description 组合模式
     * @since 2024/3/11 22:51:07
     */
    public class Main {
    
        public static void main(String[] args) {
    
            // 根节点
            Component root = new Composite("Root");
    
            // 叶子节点1、2
            Component leaf1 = new Leaf("L. one");
            Component leaf2 = new Leaf("L. two");
    
            // 子节点1
            Component node1 = new Composite("N. one");
            Component leaf3 = new Leaf("L. three");
    
            // 子节点2
            Component node2 = new Composite("N. two");
            Component leaf4 = new Leaf("L. four");
    
            // 为子节点添加叶子节点
            node1.add(leaf3);
            node2.add(leaf4);
    
            // 为根节点添加子节点、叶子节点
            root.add(leaf1);
            root.add(leaf2);
            root.add(node1);
            root.add(node2);
    
            // 输出结果,相当于中序遍历
            root.operation();
    
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 测试结果

    在这里插入图片描述

    4. 使用场景

    • 部分、整体场景,如树形菜单,文件、文件夹的管理
      在这里插入图片描述
  • 相关阅读:
    Spring MVC
    C_12练习题
    rsync远程同步
    Mac OS合集
    Dubbo负载均衡
    批量操作数据、自定义分页器
    PCI bar 解析
    JVM 参数详解
    内核!阿里技术专家不传的微服务+注册中心+网关+开源配置中心
    MySQL 主从时间字段相差1秒深度揭密
  • 原文地址:https://blog.csdn.net/Wei_Naijia/article/details/136694126