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

总结

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

相关推荐
chuanauc2 分钟前
Kubernets K8s 学习
java·学习·kubernetes
一头生产的驴18 分钟前
java整合itext pdf实现自定义PDF文件格式导出
java·spring boot·pdf·itextpdf
YuTaoShao25 分钟前
【LeetCode 热题 100】73. 矩阵置零——(解法二)空间复杂度 O(1)
java·算法·leetcode·矩阵
zzywxc78728 分钟前
AI 正在深度重构软件开发的底层逻辑和全生命周期,从技术演进、流程重构和未来趋势三个维度进行系统性分析
java·大数据·开发语言·人工智能·spring
YuTaoShao3 小时前
【LeetCode 热题 100】56. 合并区间——排序+遍历
java·算法·leetcode·职场和发展
程序员张33 小时前
SpringBoot计时一次请求耗时
java·spring boot·后端
llwszx6 小时前
深入理解Java锁原理(一):偏向锁的设计原理与性能优化
java·spring··偏向锁
Small black human6 小时前
设计模式-应用分层
设计模式
云泽野6 小时前
【Java|集合类】list遍历的6种方式
java·python·list
二进制person7 小时前
Java SE--方法的使用
java·开发语言·算法