architecture-paradigm-hexagonal
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseThe Hexagonal (Ports & Adapters) Paradigm
六边形(Ports & Adapters,端口与适配器)范式
When To Use
适用场景
- Isolating business logic from external dependencies
- Systems needing swappable adapters for testing
- 隔离业务逻辑与外部依赖
- 需要可替换适配器以支持测试的系统
When NOT To Use
不适用场景
- Small scripts or utilities without external dependencies
- Prototypes where port/adapter abstraction adds overhead
- 无外部依赖的小型脚本或工具
- 原型开发场景,此时端口/适配器抽象会增加额外开销
When to Employ This Paradigm
何时采用该范式
- When you anticipate frequent changes to databases, frameworks, or user interfaces and need the core domain logic to remain stable.
- When testing the core application requires mocking complex or slow infrastructure components.
- When the development team needs to provide clear inbound and outbound interfaces for third-party integrations.
- 当你预期数据库、框架或用户界面会频繁变更,且需要核心领域逻辑保持稳定时。
- 当核心应用测试需要模拟复杂或慢速的基础设施组件时。
- 当开发团队需要为第三方集成提供清晰的入站和出站接口时。
Adoption Steps
实施步骤
- Define Domain Ports: Identify all interactions with the core domain. Define inbound "driver ports" for actors that initiate actions (e.g., UI, CLI, automated jobs) and outbound "driven ports" for services the application consumes (e.g., database, message bus, external APIs). Express these ports as formal interfaces.
- Implement Adapters at the Edge: For each external technology, create an "adapter" that implements a port's interface. Keep the core domain entirely ignorant of the specific frameworks or libraries used in the adapters.
- Aggregate Use Cases: Organize the application's functionality into services that are built around business capabilities. These services orchestrate calls to the domain through the defined ports.
- Implement Contract Testing: validate that each adapter correctly honors the expectations of the port it implements. Use contract tests or consumer-driven contract tests to validate this behavior.
- Enforce Dependency Rules: The most critical rule is that only adapters may have dependencies on external frameworks. Enforce this with automated architecture tests or static analysis rules.
- 定义领域端口:识别所有与核心领域的交互。为发起操作的参与者(如UI、CLI、自动化任务)定义入站“驱动端口”,为应用所依赖的服务(如数据库、消息总线、外部API)定义出站“被驱动端口”。将这些端口定义为正式接口。
- 在边缘实现适配器:针对每种外部技术,创建实现端口接口的“适配器”。确保核心领域完全不了解适配器中使用的具体框架或库。
- 聚合用例:围绕业务能力将应用功能组织为服务。这些服务通过定义的端口协调对领域的调用。
- 实现契约测试:验证每个适配器是否正确遵守其实现的端口的预期。使用契约测试或消费者驱动的契约测试来验证此行为。
- 强制执行依赖规则:最关键的规则是只有适配器可以依赖外部框架。通过自动化架构测试或静态分析规则来强制执行此规则。
Key Deliverables
关键交付物
- An Architecture Decision Record (ADR) that formally names the ports, their corresponding adapters, and the dependency policies.
- A set of port interface definitions, stored with the core domain module.
- A suite of contract tests for each adapter, alongside unit tests for the domain and application services.
- Architectural diagrams showing the inbound and outbound data flows, for use by operations teams and architecture reviewers.
- 一份架构决策记录(ADR),正式命名端口、对应的适配器以及依赖策略。
- 一组端口接口定义,与核心领域模块一起存储。
- 每个适配器的契约测试套件,以及领域和应用服务的单元测试。
- 展示入站和出站数据流的架构图,供运维团队和架构评审人员使用。
Risks & Mitigations
风险与缓解措施
- Port/Interface Bloat:
- Mitigation: An excessive number of ports can increase maintenance overhead. Group related operations into more cohesive, higher-level ports, often organized around domain aggregates.
- Leaky Abstractions:
- Mitigation: If a port's interface exposes details about the transport layer (e.g., HTTP headers), it is a "leaky abstraction." Refactor these interfaces to use domain-centric Data Transfer Objects (DTOs) instead.
- Adapter Drift:
- Mitigation: An adapter can become out-of-sync with the external technology it represents (e.g., database schema changes). Schedule regular, automated validation of adapters, such as verifying that SQL migrations still align with the expectations of the persistence port.
- 端口/接口膨胀:
- 缓解方案:过多的端口会增加维护成本。将相关操作分组到更具内聚性的高层端口中,通常围绕领域聚合进行组织。
- 抽象泄漏:
- 缓解方案:如果端口接口暴露了传输层的细节(如HTTP头),则属于“抽象泄漏”。重构这些接口,改用领域中心的数据传输对象(DTOs)。
- 适配器漂移:
- 缓解方案:适配器可能与其所代表的外部技术不同步(如数据库 schema 变更)。定期自动验证适配器,例如检查SQL迁移是否仍与持久化端口的预期一致。
Troubleshooting
故障排除
Common Issues
常见问题
Command not found
Ensure all dependencies are installed and in PATH
Permission errors
Check file permissions and run with appropriate privileges
Unexpected behavior
Enable verbose logging with flag
--verbose命令未找到
确保所有依赖已安装并添加到PATH环境变量中
权限错误
检查文件权限并使用适当权限运行
异常行为
使用标志启用详细日志
--verbose