architecture-paradigm-modular-monolith

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

The Modular Monolith Paradigm

模块化单体(Modular Monolith)范式

When To Use

适用场景

  • Organizing large codebases into well-bounded modules
  • Teams wanting microservice boundaries without distributed complexity
  • 将大型代码库组织为边界清晰的模块
  • 团队希望获得微服务的边界优势,但不想承受分布式系统的复杂度

When NOT To Use

不适用场景

  • Already distributed as microservices
  • Tiny applications where module boundaries add unnecessary complexity
  • 已经拆分为微服务的分布式系统
  • 小型应用,此时添加模块边界会引入不必要的复杂度

When to Employ This Paradigm

何时采用该范式

  • When you desire team autonomy similar to that of microservices, but without the operational overhead of a distributed system.
  • When release velocity is slowed by tangled dependencies between internal modules.
  • When a monolithic architecture is simpler to operate today, but there is a clear need to evolve toward a service-based model in the future.
  • 你希望获得类似微服务的团队自主性,但不想承担分布式系统的运维开销
  • 内部模块之间的依赖混乱拖慢了发布速度
  • 当前单体架构运维更简单,但未来有明确的向服务化模型演进的需求

Adoption Steps

落地步骤

  1. Identify Modules: Define module boundaries that align with distinct business capabilities or Bounded Contexts from Domain-Driven Design.
  2. Encapsulate Internals: Use language-level visibility modifiers (e.g., public/private), separate packages, or namespaces to hide the implementation details of each module.
  3. Expose Public Contracts: Each module should expose its functionality through well-defined facades, APIs, or events. Forbid direct database table access or direct implementation calls between modules.
  4. Enforce Architectural Fitness: Implement automated tests that fail the build if forbidden dependencies or package references are introduced between modules.
  5. Plan for Evolution: Continuously track metrics such as change coupling and deployment scope to make informed decisions about if and when to split a module into a separate service.
  1. 识别模块:定义与不同业务能力或Domain-Driven Design中的限界上下文对齐的模块边界。
  2. 封装内部实现:使用语言层面的可见性修饰符(如public/private)、独立包或命名空间来隐藏每个模块的实现细节。
  3. 暴露公共契约:每个模块都应该通过定义清晰的门面、API或事件来暴露其功能,禁止模块之间直接访问数据库表或者直接调用内部实现。
  4. 保障架构合规性:实现自动化测试,如果模块之间引入了被禁止的依赖或包引用,就会导致构建失败。
  5. 规划演进路径:持续跟踪变更耦合度、部署范围等指标,为是否以及何时将某个模块拆分为独立服务的决策提供依据。

Key Deliverables

核心交付物

  • An Architecture Decision Record (ADR) that maps module boundaries and defines the rules for any shared code.
  • Formal contract documentation (e.g., OpenAPI specs, event schemas) for every interaction point between modules.
  • Automated dependency checks and dedicated CI/CD jobs for each module to enforce boundaries.
  • 架构决策记录(ADR),记录模块边界划分规则,以及所有共享代码的使用规则。
  • 模块间每个交互点的正式契约文档(如OpenAPI规范、事件schema)。
  • 自动化依赖检查,以及为每个模块配置专属的CI/CD任务来强制边界规则。

Risks & Mitigations

风险与缓解方案

  • Regression to a "Big Ball of Mud":
    • Mitigation: Without strict enforcement, module boundaries will inevitably erode. Treat any boundary violation as a build-breaking error and maintain a disciplined approach to code reviews.
  • Shared Database Hotspots:
    • Mitigation: High contention on a shared database can become a bottleneck. Introduce clear schema ownership, use view-based access to restrict data visibility, or implement data replication strategies to reduce coupling.
  • 退化回「大泥球」架构
    • 缓解方案:如果没有严格的强制规则,模块边界必然会逐渐失效。将任何边界违规视为会导致构建失败的严重错误,在代码评审中保持严格的纪律。
  • 共享数据库热点问题
    • 缓解方案:共享数据库的高争用会成为瓶颈。引入清晰的schema所有权规则,使用基于视图的访问控制来限制数据可见性,或者实现数据复制策略来降低耦合。

Troubleshooting

问题排查

Common Issues

常见问题

Skill not loading Check YAML frontmatter syntax and required fields
Token limits exceeded Use progressive disclosure - move details to modules
Modules not found Verify module paths in SKILL.md are correct
Skill加载失败 检查YAML frontmatter语法和必填字段是否正确
超过Token限制 使用渐进式披露策略——将详情迁移到模块中
找不到模块 校验SKILL.md中的模块路径是否正确