You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

领域实体方法参数接口的包选型及Ports and adapters架构下的包命名咨询

包命名与接口位置指南(基于Ports & Adapters/DDD)

Great question—this is exactly where Ports & Adapters (Hexagonal Architecture) shines, and getting the package naming right will make your codebase clean and maintainable long-term. Let’s walk through this step by step:

1. 采用Ports & Adapters命名的建议(推荐)

This is the most explicit approach for separating concerns, and it aligns perfectly with your goal of keeping the domain layer independent:

领域层包结构

  • 核心领域实体放在 com.yourapp.todo.domain(比如你的 Task 类)
  • 把 ToFileSaver 接口放在 com.yourapp.todo.domain.ports.out
    • 原因:在Ports & Adapters术语里,这是一个输出端口——它是领域定义的契约,告诉外部系统“我需要你这样来保存我的数据”。领域不关心实现细节,只要求契约被满足。

基础设施层包结构

  • 基础设施层根包:com.yourapp.todo.infrastructure
  • 实现 ToFileSaver 的类(比如 FileSystemFileSaver)放在 com.yourapp.todo.infrastructure.adapters.out.filesystem
    • 这样命名能清晰表明这是一个输出适配器:它是把领域的输出端口和具体技术(比如文件系统)连接起来的具体实现。

2. 非Ports & Adapters命名替代方案

如果你偏好更通用的术语(仍符合DDD思想):

  • 领域层接口可以放在 com.yourapp.todo.domain.spi(SPI = Service Provider Interface)——这是ports.out的常见替代命名,表达的含义一致:领域对外暴露的、供外部实现的契约。
  • 基础设施层实现可以放在 com.yourapp.todo.infrastructure.persistence 或 com.yourapp.todo.infrastructure.file——只要能明确和领域层分离,且绑定到具体技术即可。

3. 关键:领域实体方法参数的接口位置

ToFileSaver接口必须放在领域层(domain.ports.out或domain.spi),原因如下:

  • 你的Task是领域实体,它应该只依赖领域层的代码。如果把接口放在基础设施层,会形成反向依赖(领域依赖基础设施),这完全违背了分层架构的核心原则。
  • 把接口留在领域层,能保持领域的纯粹性:它定义自己的需求,外部系统去适配它,而不是反过来。

示例目录结构

com/
  yourapp/
    todo/
      domain/
        Task.java
        ports/
          out/
            ToFileSaver.java
      infrastructure/
        adapters/
          out/
            filesystem/
              FileSystemFileSaver.java
      application/  # 可选:协调领域逻辑与基础设施
        TaskService.java

内容的提问来源于stack exchange,提问作者Sampeteq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 03:37:34