设计模式Java实现-组合模式

✨这里是第七人格的博客✨小七,欢迎您的到来~✨

🍅系列专栏:设计模式🍅

✈️本篇内容:组合模式✈️

🍱本篇收录完整代码地址:gitee.com/diqirenge/d...🍱

楔子

小七最近工作可以说是忙到飞起,本来想着今天休息一下就不再更新了。但是!但是!但是!

今天下午居然被群友推荐鼓励了o( ̄▽ ̄)ブ,那必须得再干它一篇!

ps:有些朋友觉得设计模式太简单了,希望小七聊聊JUC和Spring源码。小七只想说不要方(●ˇ∀ˇ●),等设计模式这个专栏写完了,就开始更新JUC相关知识。

大纲都已经有了,可以浏览小七的github-page尝尝鲜 li-zong-yang.github.io/#/guide_ind...

需求背景

2022年小七研究过一段时间的接口编排,当时还给liteFlow提过一个Issues

Issues中举例的业务场景就很适合使用组合模式。

我们再将这个需求简单描述一下:

1、我们有2种检验注册的手段 a.手机号 b身份证

2、这两种校验手段在不同的业务场景下,有不同的组合,可以都参与校验,也可以只有一个参与校验。

分析设计

为了让我们的校验功能,能够进⾏⾃由组合对外提供服务。我们可以把这两种校验手段想象成两片叶子,他们可以自由组合成一棵完整的树。

首先我们抽象出组件接口ComponentChecker,让两个具体的校验类都实现它;

然后我们定义组合节点Composite,可以先理解成图中的root,它里面要包含子节点,所以我们得有一个list的属性

java 复制代码
/**
 * 可以存放子节点
 */
private List<ComponentChecker> children;

UML图

根据分析设计,我们可以先画一个简单的UML图,后面通过UML图编码

模块名称

composite

模块地址

gitee.com/diqirenge/d...

模块描述

组合模式代码示例

代码实现

1、定义组件接口

java 复制代码
/**
 * 定义组件接口
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/11/30
 */
public interface ComponentChecker {
    /**
     * 校验
     */
    void check();
}

具体实现子类-身份证校验器

java 复制代码
/**
 * 子节点 - 身份证校验器
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/11/30
 */
class IdCardChecker implements ComponentChecker {
    private String number;

    public IdCardChecker(String number) {
        this.number = number;
    }

    @Override
    public void check() {
        System.out.println("校验身份证[" + number + "]被执行了...");
    }

    @Override
    public String toString() {
        return "IdCard{" +
                "number='" + number + '\'' +
                '}';
    }
}

具体实现子类-电话校验器

java 复制代码
/**
 * 子节点 - 电话校验器
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/11/30
 */
class PhoneChecker implements ComponentChecker {
    private String number;

    public PhoneChecker(String number) {
        this.number = number;
    }

    @Override
    public void check() {
        System.out.println("校验电话号码[" + number + "]被执行了...");
    }

    @Override
    public String toString() {
        return "Phone{" +
                "number='" + number + '\'' +
                '}';
    }
}

2、定义组合节点

关键点是要将组件接口的集合作为属性放到类中

java 复制代码
/**
 * 定义组合节点
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/11/30
 */
class Composite implements ComponentChecker {
    private String name;
    /**
     * 可以存放子节点
     */
    private List<ComponentChecker> children;

    public Composite(String name) {
        this.name = name;
        this.children = new ArrayList<>();
    }

    /**
     * 添加子节点
     *
     * @param child 添加的节点
     */
    public void addChild(ComponentChecker child) {
        children.add(child);
    }

    /**
     * 移除子节点
     *
     * @param child 删除的节点
     */
    public void removeChild(ComponentChecker child) {
        children.remove(child);
    }

    @Override
    public void check() {
        System.out.println("组合节点[" + name + "]准备开始执行\n叶子节点数据为:" + children.toString() + "\n");
        for (ComponentChecker child : children) {
            child.check();
        }
    }

    @Override
    public String toString() {
        return "Composite{" +
                "name='" + name + '\'' +
                ", children=" + children +
                '}';
    }
}

3、编写测试类

java 复制代码
/**
 * 测试组合模式
 * 关注公众号【奔跑的码畜】,一起进步不迷路
 *
 * @author 第七人格
 * @date 2023/11/29
 */
public class CompositeTest {
    @Test
    public void testBridge() {
        // 创建根节点,他是一个组合节点
        Composite root = new Composite("根节点");

        // 创建叶子节点1
        IdCardChecker leaf1 = new IdCardChecker("500383*********");
        root.addChild(leaf1);

        // 创建叶子节点2
        PhoneChecker leaf2 = new PhoneChecker("186*********");
        root.addChild(leaf2);

        // 执行操作
        root.check();
    }
}

5、测试结果

组合节点[根节点]准备开始执行

叶子节点数据为:[IdCard{number='500383 * * * * * * * * * '}, Phone{number='186 * * * * * * * * *'}]

校验身份证[500383 * * * * * * * * * *]被执行了...

校验电话号码[186* * * * * * * * * * * *]被执行了...

实现要点

  1. 抽象组件(Component):定义创建对象的接口,允许客户端独立地获取组件对象。

    文中示例为:ComponentChecker

  2. 叶子节点(Leaf):继承/实现自抽象组件,表示叶子节点对象。

    文中示例为:IdCardChecker和PhoneChecker

  3. 容器节点(Composite):继承自抽象组件,表示容器节点对象,包含子组件列表。

    文中示例为:Composite;子组件列表为:private List children。

总结

组合模式是一种结构型设计模式,它将对象组织成树形结构,使得客户端可以以统一的方式处理单个对象和组合对象。

相关推荐
风象南3 分钟前
SpringBoot配置属性热更新的轻量级实现
java·spring boot·后端
洛阳泰山3 分钟前
Spring Boot 整合 Nacos 实战教程:服务注册发现与配置中心详解
java·spring boot·后端·nacos
Y4090014 分钟前
C语言转Java语言,相同与相异之处
java·c语言·开发语言·笔记
YuTaoShao5 分钟前
【LeetCode 热题 100】994. 腐烂的橘子——BFS
java·linux·算法·leetcode·宽度优先
布朗克1685 分钟前
java常见的jvm内存分析工具
java·jvm·数据库
都叫我大帅哥1 小时前
深入浅出 Resilience4j:Java 微服务的“免疫系统”实战指南
java·spring cloud
Cao_Shixin攻城狮3 小时前
Flutter运行Android项目时显示java版本不兼容(Unsupported class file major version 65)的处理
android·java·flutter
Dcs6 小时前
还在用 Arrays.hashCode?Java 自己也能写出更快的版本!
java
fouryears_234178 小时前
Spring,Spring Boot 和 Spring MVC 的关系以及区别
java·spring boot·spring·mvc
阿葱(聪)8 小时前
java 在k8s中的部署流程
java·开发语言·docker·kubernetes