设计模式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。

总结

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

相关推荐
小荷才露尖尖角,早有蜻蜓立上头21 分钟前
过滤器的4种创建方式
java
大圣编蚕31 分钟前
Java ByteArrayInputStream 详解:从入门到实战
java·开发语言·算法
程序员阿明1 小时前
idea把插件啥的不默认放在C盘
java·ide·intellij-idea
linweidong1 小时前
中科闻歌Java面试题及参考答案
java·python·大模型·提示词·ai agent·mcp·rag原理
OpenAnolis小助手2 小时前
一句话看透 JVM,SysOM 诊断 Skill 新增 Java 应用诊断能力
java·开发语言·jvm·阿里云·操作系统控制台·sysom
ForteScarlet2 小时前
Kotlin 2.4.20 现已发布,新特性多不多?
android·java·开发语言·开源·kotlin·jetbrains
萧瑟余晖2 小时前
Java深入解析篇六十二之安全机制详解
java·开发语言
小刘在重生~2 小时前
Java 常用类|包装类 装箱拆箱、Integer 缓存面试题
java·python·缓存
Orange_sparkle2 小时前
Pi Agent vs LangGraph:从人机交互、企业 RAG 到持久化工作流的完整选型指南
java·网络·人机交互
Wang's Blog4 小时前
Java框架快速入门: Spring Security+OAuth2之过滤器与过滤器链
java·开发语言·spring