mcpField
A
architecture-patterns

architecture-patterns

github.com/full-stack-skills开发383 次安装5 周前更新
代码仓库

关于 architecture-patterns

面向后端开发的架构模式技能,涵盖整洁架构、六边形架构和领域驱动设计。它帮助开发者在设计或重构系统时明确分层、接口边界与测试方式。

主要功能

  1. 01整洁架构分层指导
  2. 02端口与适配器设计模式
  3. 03DDD 战略与战术模式
  4. 04依赖循环排查建议
  5. 05内存适配器测试指导

适用场景

  1. 01设计新的后端服务
  2. 02重构业务逻辑纠缠的单体
  3. 03拆分服务前定义限界上下文
  4. 04无需数据库测试用例

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/full-stack-skills/python-skills --skill architecture-patterns

安装后在 Claude Code 中输入/architecture-patterns确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE.txt
SKILL.md.backup
agents/
openai.yaml
examples/
advanced-usage.md
basic-usage.md
integration.md
references/
advanced-patterns.md
details.md

详细介绍

来源声明:本技能内容源自 wshobson/agents (MIT License,Copyright (c) 2024 Seth Hobson;完整许可文本见同目录 LICENSE.txt)。 使用、修改与再分发须遵守该 MIT 许可条款并保留版权声明。

中文描述

本技能提供全栈开发相关的最佳实践和模式指导。


name: architecture-patterns description: 实施经过验证的后端架构模式,包括 Clean Architecture、Hexagonal Architecture 和 Domain-Driven Design。在为新微服务设计 Clean Architecture、重构单体以使用有界上下文、实施六边形或洋葱架构模式,或调试应用层之间的依赖循环时,使用此技能。

架构模式

掌握经过验证的后端架构模式,包括 Clean Architecture、Hexagonal Architecture 和 Domain-Driven Design,以构建易于维护、可测试且可扩展的系统。

输入: 要设计架构的服务边界或模块。 产出: 具有清晰依赖规则、接口定义和测试边界的分层结构。

何时使用此技能

  • 从头设计新的后端服务或微服务
  • 重构业务逻辑与 ORM 模型或 HTTP 相关逻辑纠缠在一起的单体应用
  • 在将系统拆分为多个服务前建立有界上下文
  • 调试基础设施代码渗入领域层所导致的依赖循环
  • 创建无需运行数据库即可测试用例的可测试代码库
  • 实施领域驱动设计战术模式(聚合、值对象、领域事件)

核心概念

1. Clean Architecture(Uncle Bob)

分层(依赖向内流动):

  • 实体:核心业务模型,不导入框架
  • 用例:应用业务规则,协调实体
  • 接口适配器:控制器、表示器、网关——在用例与外部格式之间进行转换
  • 框架与驱动程序:UI、数据库、外部服务——均位于最外层

关键原则:

  • 依赖只能向内指向;内层不了解外层
  • 业务逻辑独立于框架、数据库和交付机制
  • 每个层边界都通过抽象接口跨越
  • 无需 UI、数据库或外部服务即可测试
2. Hexagonal Architecture(端口与适配器)

组成部分:

  • 领域核心:业务逻辑位于此处,不依赖框架
  • 端口:定义核心如何与外部世界交互的抽象接口(驱动端和被驱动端)
  • 适配器:端口的具体实现(PostgreSQL 适配器、Stripe 适配器、REST 适配器)

优势:

  • 无需触碰核心即可替换实现(例如,将 PostgreSQL 替换为 DynamoDB)
  • 在测试中使用内存适配器——无需 Docker
  • 将技术选型推迟到边界层
3. Domain-Driven Design(DDD)

战略模式:

  • 有界上下文:为一个子域隔离出连贯的模型;避免整个系统共享单一模型
  • 上下文映射:定义上下文之间的关系(防腐层、共享内核、开放主机服务)
  • 通用语言:代码中的每个术语都与领域专家使用的术语一致

战术模式:

  • 实体:具有稳定标识且会随时间变化的对象
  • 值对象:由其属性标识的不可变对象(Email、Money、Address)
  • 聚合:一致性边界;外部只能访问根对象
  • 仓储:持久化并重新构建聚合;对存储机制进行抽象
  • 领域事件:记录领域内发生的事情;用于跨聚合协调

详细模式和完整示例

详细模式文档位于 references/details.md。上面的导航层级无法满足需要时,请阅读该文件。

测试 — 内存适配器

正确应用整洁架构的标志是:每个用例都可以通过简单的单元测试进行测试,无需真实数据库、Docker 或网络:

# tests/unit/test_create_user.py
import asyncio
from typing import Dict, Optional
from domain.entities.user import User
from domain.interfaces.user_repository import IUserRepository
from use_cases.create_user import CreateUserUseCase, CreateUserRequest


class InMemoryUserRepository(IUserRepository):
    def __init__(self):
        self._store: Dict[str, User] = {}

    async def find_by_id(self, user_id: str) -> Optional[User]:
        return self._store.get(user_id)

    async def find_by_email(self, email: str) -> Optional[User]:
        return next((u for u in self._store.values() if u.email == email), None)

    async def save(self, user: User) -> User:
        self._store[user.id] = user
        return user

    async def delete(self, user_id: str) -> bool:
        return self._store.pop(user_id, None) is not None


async def test_create_user_succeeds():
    repo = InMemoryUserRepository()
    use_case = CreateUserUseCase(user_repository=repo)

    response = await use_case.execute(CreateUserRequest(email="[email protected]", name="Alice"))

    assert response.success
    assert response.user.email == "[email protected]"
    assert response.user.id is not None


async def test_duplicate_email_rejected():
    repo = InMemoryUserRepository()
    use_case = CreateUserUseCase(user_repository=repo)

    await use_case.execute(CreateUserRequest(email="[email protected]", name="Alice"))
    response = await use_case.execute(CreateUserRequest(email="[email protected]", name="Alice2"))

    assert not response.success
    assert "already exists" in response.error

故障排查

用例测试需要运行中的数据库

业务逻辑泄漏到了基础设施层。将所有数据库调用移到 IRepository 接口后,并在测试中注入内存实现(参见上文的“测试”部分)。用例构造函数必须接受抽象端口,而不是具体类。

各层之间出现循环导入

常见症状是 use_cases 和 adapters 之间出现 ImportError: cannot import name X。这是因为用例导入了具体适配器类,而不是抽象端口。请遵循以下规则:use_cases/ 只能从 domain/(实体和接口)导入内容,绝不能从 adapters/ 或 infrastructure/ 导入。

领域实体中出现框架装饰器

如果领域实体上出现 SQLAlchemy Column() 或 Pydantic Field() 注解,说明实体已不再纯粹。请在 adapters/repositories/ 中创建独立的 ORM 模型,并在存储库的 _to_entity() 方法中将其映射为领域实体或从领域实体映射。

所有逻辑都塞进控制器

当控制器的职责超出解析 HTTP 请求和格式化响应时,应将逻辑提取到用例类中。控制器方法只应做三件事:解析请求、调用用例、映射响应。

值对象延迟报错

在 __post_init__(Python)或构造函数中验证不变量,确保无法构造无效的 Email 或 Money。这样可以在边界处发现无效数据,而不是等到深入业务逻辑后才发现。

有界上下文之间出现上下文泄漏

如果 Order 上下文导入了 Identity 上下文中的 User 实体,请引入防腐层。Order 上下文应持有自己的轻量级 CustomerId 值对象,并且只通过显式接口调用 Identity 上下文。

高级模式

如需了解详细的 DDD 有界上下文映射、完整的多服务项目目录结构、防腐层实现以及洋葱架构对比,请参阅:

相关技能

  • microservices-patterns — 将单体拆分为服务时应用这些架构模式
  • cqrs-implementation — 使用整洁架构作为 CQRS 命令/查询分离的结构基础
  • saga-orchestration — Saga 需要明确界定聚合边界,而 DDD 战术模式可提供这些边界
  • event-store-design — 聚合产生的领域事件会直接进入事件存储

工作流程

步骤 1:需求分析

理解项目需求和技术约束

步骤 2:架构设计

设计系统架构和组件划分

步骤 3:实现指导

提供具体的实现建议和代码模式

步骤 4:代码审查

审查代码质量和最佳实践遵循情况

步骤 5:优化建议

提供性能优化和改进建议

注意事项

1. 过度设计

避免在简单场景中使用复杂的设计模式

2. 忽视性能

不要忽视性能优化,特别是在生产环境中

3. 安全考虑

始终考虑安全性和数据保护

4. 测试覆盖

确保有足够的测试覆盖,特别是边界情况

5. 文档维护

保持文档与代码同步更新

评论

支持 Markdown