今天学习了为什么要在一个小项目中引入另一个项目的请求/响应层 加深了我的个人理解

因为这是微服务架构中 “管理后台(admin)与核心服务(project)解耦” 的典型设计

接下来我将从五点来对本次学习进行一个学习总结

一、为什么复制 req/resp 到 admin 项目?(核心:隔离与兼容)

场景:

  • project 是短链接核心服务(负责生成、存储短链接)。

  • admin 是管理后台(负责分页查询、统计等管理功能)。

复制原因:

  1. 避免直接依赖核心服务代码

  • 如果 admin 直接引用 project 的 ShortLinkPageReqDTO,会导致:

  • 核心服务代码变更时,admin 必须同步修改(耦合严重)。

  • 部署时 admin 依赖 project 的 jar 包,违背微服务 “独立部署” 原则。

  • 复制 DTO 后,admin 只关心 “接口契约”(字段名、类型),不关心核心服务的实现细节。

  1. 数据格式对齐

  • 管理后台的查询参数(如 gid、分页参数)必须与核心服务的接口输入 / 输出完全一致,否则远程调用会失败。

  • 复制 DTO 是最简单的 “契约对齐” 方式(比用 Swagger 自动生成更直接)。

二、为什么在 admin 中创建 ShortLinkRemoteService?(核心:远程调用封装)

代码作用:

java

public interface ShortLinkRemoteService {
    default Result<IPage<ShortLinkPageRespDTO>> pageShortLink(ShortLinkPageReqDTO requestParam) {
        // 1. 将参数转为 Map(HTTP 请求参数)
        // 2. 调用核心服务的 HTTP 接口
        // 3. 解析返回的 JSON 为 Result 对象
    }
}

这是 “远程服务代理”,作用是:

  1. 隐藏远程调用细节

  • 管理后台的业务代码(如 Controller)无需关心 “核心服务是 HTTP 还是 RPC 调用”,只需调用 ShortLinkRemoteService 的方法。

  • 未来如果核心服务从 HTTP 改为 Dubbo 或 gRPC,只需修改 default 方法的实现,不影响上层调用。

  1. 适配管理后台的业务逻辑

  • 核心服务返回的 IPage 可能包含敏感字段(如数据库主键),ShortLinkPageRespDTO 可以裁剪为管理后台需要的字段(如只保留短链接、创建时间)。

三、为什么没有实现类?(核心:Java 接口的 default 方法特性)

常规写法 vs 你的代码:

方式

常规分层(有实现类)

你的代码(无实现类,用 default

定义

interface + @Service 实现类

接口中直接写 default

方法

适用场景

复杂业务逻辑(需要 Spring 注解)

简单远程调用(无需 Spring 管理)

优点

支持 AOP(如日志、事务)

轻量级,无需额外类

缺点

代码冗余

难扩展复杂逻辑

你的代码选择 default 的原因:

  • 轻量级远程调用:管理后台只需要简单的分页查询,直接用 Hutool 的 HttpUtil 调用,避免创建 @Service 类和 Spring 配置。

  • 临时过渡方案:如果未来需要添加重试、熔断等功能,可以再创建实现类覆盖 default 方法:java

@Service
public class ShortLinkRemoteServiceImpl implements ShortLinkRemoteService {
    @Override
    public Result<IPage<ShortLinkPageRespDTO>> pageShortLink(ShortLinkPageReqDTO requestParam) {
        // 新增重试逻辑 + 原 default 逻辑
    }
}



四、为什么在 admin 中创建 Controller?(核心:分层职责)

管理后台的 ShortLinkController 职责:

  1. 接收前端请求:解析分页参数(currentsize)和业务参数(gid)。

  2. 调用远程服务:通过 ShortLinkRemoteService 发起核心服务的查询。

  3. 返回响应:将远程结果转换为前端需要的格式(如去除技术字段,保留业务字段)。

不直接在 Controller 写 HTTP 调用的原因(对比代码):

方式

直接写 HTTP 调用(坏味道)

通过 Service 调用(好味道)

代码位置

Controller 混杂 HTTP 逻辑

封装到 RemoteService,Controller 更纯净

可测试性

难 Mock 远程服务

容易 Mock ShortLinkRemoteService

复用性

无法复用查询逻辑

其他 Controller 可共享该服务

五、总结:这套代码的设计思想

1. 微服务解耦

  • admin 与 project 是独立服务,通过 HTTP 接口通信,复制 DTO 是 “接口契约” 的显式声明。

2. 分层瘦身

  • 管理后台不需要完整的三层(Service+DAO),因为不直接操作数据库,只需要 “Controller + 远程服务代理”。

  • default 方法是 “够用即可” 的设计,避免为简单功能创建冗余类。

3. 演进预留

  • 现在用 HTTP 直连,未来可以无缝切换为 Feign/RestTemplate 等更优雅的远程调用方案,只需修改 ShortLinkRemoteService