轻量级Java跨包调用(完全解耦)

Java函数式命令模式

        轻量级跨包调用解耦方案,让跨包调用就像调用本地接口那样简单。适用与具有公共依赖的两个jar包,但是又不想相互引入对方作为依赖。

        函数式命令模式,很好地实现了跨包调用解耦的目标,并且通过泛型+JSON动态转换保证了灵活性。

        设计决策:

特性

实现效果

优势

跨包调用

通过字符串Key调用,完全消除编译期依赖

模块完全隔离

类型安全

泛型+ Class<T> 确保参数类型正确

避免运行时类型错误

轻量简洁

无状态无复杂继承结构,直接函数式调用

比传统命令模式更简洁

JSON兼容

天然支持RPC/微服务改造(未来如需)

轻松改造成RPC调用

        常量命令:

public interface Command {
    String CMD_MENU_SAVE = "menu.save";
}

        命令操作系统:

public abstract class OperateSystem {
    private static final Map<String, Function<JSONObject, ?>> COMMAND_MAP = new HashMap<>();

    public static <T, R> void registerCommand(String command, Class<T> paramType, Function<T, R> receiver) {
        COMMAND_MAP.put(command, json -> {
            T param = json.toJavaObject(paramType);
            if (ObjectUtils.isEmpty(param)) {
                throw new CommonException("Parameter parsing failed, expected type: %s", paramType.getName());
            }

            String message = BeanUtils.parseEmptyField(param);
            if (StringUtils.isNotBlank(message)) {
                throw new CommonException("Parameter validation failed: %s", message);
            }

            return receiver.apply(param);
        });
    }


    public static void unregisterCommand(String command) {
        COMMAND_MAP.remove(command);
    }

    public static <R> R execute(String command, JSONObject param) {
        Function<JSONObject, R> function = getJsonFunction(command);
        return function.apply(param);
    }

    @SuppressWarnings("unchecked")
    private static <R> Function<JSONObject, R> getJsonFunction(String command) {
        Function<JSONObject, R> function = (Function<JSONObject, R>) COMMAND_MAP.get(command);
        if (ObjectUtils.isEmpty(function)) {
            throw new CommonException("Unregistered command: %s", command);
        }
        return function;
    }

    @SuppressWarnings("unchecked")
    public static <R, E> E execute(String command, Class<E> resultType, JSONObject param) {
        if (ObjectUtils.isEmpty(resultType)) {
            throw new CommonException("Command result type can not be null: %s", command);
        }

        Function<JSONObject, R> function = getJsonFunction(command);
        R result = function.apply(param);
        if (ObjectUtils.isEmpty(result)) {
            return null;
        }

        if (resultType.isInstance(result)) {
            return (E)result;
        }

        throw new CommonException("Command [%s] failed to produce the expected result." +
                " Expected type: %s, Actual type: %s", command,
                resultType.getName(), result.getClass().getName());
    }

}

        上述两个代码放在公共依赖包中,如common.jar。

        模块接收者(引入common.jar依赖):

@PostConstruct  // 依赖注入完成后初始化函数
private void registerCommand() {
    OperateSystem.registerCommand(Command.CMD_MENU_SAVE, SaveMenu.class, this::saveMenu);
}

public Boolean saveMenu(SaveMenu saveMenu) {
    ... ...
}

        模块调用者(引入common.jar依赖):

public void analyseBuildCache() {
    ... ...

    String rootPath = this.engineer.getInterfaceRootPath();
    JSONObject param = new JSONObject();
    param.put("title", rootPath);
    param.put("code", StringUtils.absoluteLowerUnderlineLetter(rootPath));
    param.put("routePath", rootPath);

    String webPackagePath = this.engineer.getWebPackagePath();
    param.put("componentPath", webPackagePath.substring(6));
    param.put("sort", 1);
    OperateSystem.execute(Command.CMD_MENU_SAVE, param);
}

        对比传统方法:

方案

当前实现

Spring依赖注入

RPC调用

跨包隔离

✅ 完全隔离

❌ 需暴露接口

✅ 隔离

类型安全

✅ 运行时校验

✅ 编译期检查

❌ 需额外契约

代码量

⭐ 极少

⭐⭐ 中等

⭐⭐⭐ 复杂

性能

⭐⭐⭐ 直接调用

⭐⭐⭐ 直接调用

⭐ 网络开销

适用场景

        推荐使用:

        ✅ 模块化架构中的跨包调用;

        ✅ 需要快速开发且避免依赖传染的场景;

        ✅ 未来可能改为微服务但不想提前引入复杂设计。

        不推荐使用:

        ❌ 需要编译期强类型检查(考虑接口下沉)。

        ❌ 需要支持事务/重试等复杂控制流(考虑Spring事务代理)。

        命令模式核心:

        "将请求封装为对象,从而使你可以参数化其他对象使用不同的请求"
                                                                                ----《设计模式:可复用面向对象软件的基础》

本文为作者(难拳)原创,转载请注明出处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/76141.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

离散数学问题集--问题5.9

问题 5.9 综合了计算机组成原理、数字逻辑和离散数学中的关键概念&#xff0c;旨在帮助学生理解二进制算术运算的硬件实现、逻辑门与算术运算的关系&#xff0c;以及如何使用数学方法来验证数字系统的正确性。它强调了从规范到实现再到验证的完整过程。 思想 函数抽象&#xf…

OpenLayers:海量图形渲染之矢量切片

最近由于在工作中涉及到了海量图形渲染的问题&#xff0c;因此我开始研究相关的解决方案。在咨询了许多朋友之后发现矢量切片似乎是行业内最常用的一种解决方案&#xff0c;于是我便开始研究它该如何使用。 一、什么是矢量切片 矢量切片按照我的理解就是用栅格切片的方式把矢…

神经网络入门—自定义网络

网络模型 定义一个两层网络 import torch import torch.nn as nn import torch.optim as optim import torch.nn.functional as F# 定义神经网络模型 class Net(nn.Module):def __init__(self, init_x0.0):super().__init__()self.fc1 nn.Linear(1, 10)self.fc2 nn.Linear(…

无人机装调与测试

文章目录 前言一、无人机基本常识/预备知识&#xff08;一&#xff09;无人机飞行原理无人机硬件组成/各组件作用1.飞控2.GPS3.接收机4.电流计5.电调6.电机7.电池8.螺旋桨9.UBEC&#xff08;稳压模块&#xff09; &#xff08;二&#xff09;飞控硬件简介&#xff08;三&#x…

2024年-全国大学生数学建模竞赛(CUMCM)试题速浏、分类及浅析

2024年-全国大学生数学建模竞赛(CUMCM)试题速浏、分类及浅析 全国大学生数学建模竞赛&#xff08;China Undergraduate Mathematical Contest in Modeling&#xff09;是国家教委高教司和中国工业与应用数学学会共同主办的面向全国大学生的群众性科技活动&#xff0c;目的在于激…

Linux入门指南:从零开始探索开源世界

&#x1f680; 前言 大家好&#xff01;今天我们来聊一聊Linux这个神奇的操作系统~ &#x1f916; 很多小伙伴可能觉得Linux是程序员专属&#xff0c;其实它早已渗透到我们生活的各个角落&#xff01;本文将带你了解Linux的诞生故事、发行版选择攻略、应用领域&#xff0c;还有…

记录vscode连接不上wsl子系统下ubuntu18.04问题解决方法

记录vscode连接不上wsl子系统下ubuntu18.04问题解决方法 报错内容尝试第一次解决方法尝试第二次解决方法注意事项参考连接 报错内容 Unable to download server on client side: Error: Request downloadRequest failed unexpectedly without providing any details… Will tr…

Cursor+MCP学习记录

参考视频 Cursor MCP 王炸&#xff01;彻底颠覆我的Cursor工作流&#xff0c;效率直接起飞_哔哩哔哩_bilibili 感觉这个博主讲的还不错 所使用到的网址 Smithery - Model Context Protocol Registry Introduction - Model Context Protocol 学习过程 Smithery - Model …

testflight上架ipa包-只有ipa包的情况下如何修改签名信息为苹果开发者账户对应的信息-ipa苹果包如何手动改签或者第三方工具改签-优雅草卓伊凡

testflight上架ipa包-只有ipa包的情况下如何修改签名信息为苹果开发者账户对应的信息-ipa苹果包如何手动改签或者第三方工具改签-优雅草卓伊凡 直接修改苹果IPA包的签名和打包信息并不是一个推荐的常规做法&#xff0c;因为这可能违反苹果的开发者条款&#xff0c;并且可能导致…

深入解析Java内存与缓存:从原理到实践优化

一、Java内存管理&#xff1a;JVM的核心机制 1. JVM内存模型全景图 ┌───────────────────────────────┐ │ JVM Memory │ ├─────────────┬─────────────────┤ │ Thread │ 共享…

紫光展锐5G SoC T8300:影像升级,「定格」美好世界

影像能力已成为当今衡量智能手机性能的重要标尺之一。随着消费者对手机摄影需求日益提升&#xff0c;手机厂商纷纷在影像硬件和算法上展开激烈竞争&#xff0c;力求为用户带来更加出色的拍摄体验。 紫光展锐专为全球主流用户打造的畅享影音和游戏体验的5G SoC——T8300&#x…

【Java设计模式】第6章 抽象工厂模式讲解

6. 抽象工厂模式 6.1 抽象工厂讲解 定义:提供一个接口创建一系列相关或依赖对象,无需指定具体类。核心概念: 产品等级结构:同一类型的不同产品(如Java视频、Python视频)。产品族:同一工厂生产的多个产品(如Java视频 + Java手记)。适用场景: 需要创建多个相关联的产品…

Dify教程01-Dify是什么、应用场景、如何安装

Dify教程01-Dify是什么、应用场景、如何安装 大家好&#xff0c;我是星哥&#xff0c;上篇文章讲了Coze、Dify、FastGPT、MaxKB 对比&#xff0c;今天就来学习如何搭建Dify。 Dify是什么 **Dify 是一款开源的大语言模型(LLM) 应用开发平台。**它融合了后端即服务&#xff08…

Java后端开发-面试总结(集结版)

第一个问题&#xff0c;在 Java 集合框架中&#xff0c;ArrayList和LinkedList有什么区别&#xff1f;在实际应用场景中&#xff0c;应该如何选择使用它们&#xff1f; ArrayList 基于数组&#xff0c;LinkedList 基于双向链表。 在查询方面 ArrayList 效率高&#xff0c;添加…

nslookup、dig、traceroute、ping 这些工具在解析域名时是否查询 DNS 服务器 或 本地 hosts 文件 的详细对比

host配置解析 127.0.0.1 example.comdig 测试&#xff0c;查询 DNS 服务器 nslookup测试&#xff0c;查询 DNS 服务器 traceroute测试&#xff0c;先读取本地 hosts 文件&#xff0c;再查询 DNS 服务器 ping测试&#xff0c;先读取本地 hosts 文件&#xff0c;再查询 DNS 服务…

文件上传、读取与包含漏洞解析及防御实战

一、漏洞概述 文件上传、读取和包含漏洞是Web安全中常见的高危风险点&#xff0c;攻击者可通过此类漏洞执行恶意代码、窃取敏感数据或直接控制服务器。其核心成因在于开发者未对用户输入内容进行充分验证或过滤&#xff0c;导致攻击者能够绕过安全机制&#xff0c;上传或执行…

STM32 的编程方式总结

&#x1f9f1; 按照“是否可独立工作”来分&#xff1a; 库/方式是否可独立使用是否依赖其他库说明寄存器裸写✅ 是❌ 无完全自主控制&#xff0c;无库依赖标准库&#xff08;StdPeriph&#xff09;✅ 是❌ 只依赖 CMSIS自成体系&#xff08;F1专属&#xff09;&#xff0c;只…

Flutter命令行打包打不出ipa报错

Flutter打包ipa报错解决方案 在Flutter开发中&#xff0c;打包iOS应用时可能会遇到以下错误&#xff1a; error: exportArchive: The data couldn’t be read because it isn’ in the correct format. 或者 Encountered error while creating the IPA: error: exportArchive…

SQL Server常见问题的分类解析(一)

以下是SQL Server常见问题的分类解析,涵盖安装配置、性能优化、备份恢复、高可用性等核心场景,结合微软官方文档和社区实践整理而成(编号对应搜索结果来源): 一、安装与配置问题 安装失败:.NET Framework缺失解决方案:手动安装所需版本.NET Framework,以管理员身份运行…

Spring Boot 3.x 下 Spring Security 的执行流程、核心类和原理详解,结合用户描述的关键点展开说明,并以表格总结

以下是 Spring Boot 3.x 下 Spring Security 的执行流程、核心类和原理详解&#xff0c;结合用户描述的关键点展开说明&#xff0c;并以表格总结&#xff1a; 1. Spring Security 核心原理 Spring Security 通过 Filter 链 实现安全控制&#xff0c;其核心流程如下&#xff1a…