DEV Community

架构师小白
架构师小白

Posted on

整洁架构完全指南:构建可维护、可测试的软件系统

整洁架构完全指南:构建可维护、可测试的软件系统

在软件开发的职业生涯中,你是否曾遇到过这样的困境:代码改不动、不敢改、改了就会出问题?这往往是架构腐化的信号。今天,让我们一起探索整洁架构(Clean Architecture)——一种能让你的代码保持整洁、易于维护的架构设计原则。

什么是整洁架构?

整洁架构是由Robert C. Martin(也就是我们熟知的"Uncle Bob")提出的一种软件架构设计原则。它的核心思想是将软件分层,使每一层都只依赖于其内部的层,从而实现:

  • 高内聚、低耦合:各模块职责明确,依赖方向统一
  • 易于测试:业务逻辑可以独立于外部设施进行测试
  • 可维护:修改某一层的实现不影响其他层
  • 可替换:数据库、UI等外部组件可以轻松替换

整洁架构的核心分层

┌─────────────────────────────────────────┐
│           表现层 (Presentation)         │
│    控制器、视图、API接口、DTO转换         │
├─────────────────────────────────────────┤
│           应用层 (Application)            │
│        用例、命令处理、事务管理           │
├─────────────────────────────────────────┤
│             领域层 (Domain)              │
│     实体、值对象、领域服务、业务规则       │
├─────────────────────────────────────────┤
│           基础设施层 (Infrastructure)    │
│   数据库、第三方服务、文件系统、缓存       │
└─────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

1. 领域层(Domain Layer)—— 最核心

这是软件的心脏,包含:

  • 实体(Entity):具有唯一标识的对象
  • 值对象(Value Object):没有唯一标识的属性集合
  • 领域服务(Domain Service):处理复杂的业务逻辑
  • 聚合根(Aggregate Root):控制聚合内的一致性

关键原则:领域层不依赖任何外部层,它是纯粹的业务逻辑。

# 领域层示例:订单实体
class Order:
    def __init__(self, order_id, customer):
        self.id = order_id
        self.customer = customer
        self.items = []
        self.status = OrderStatus.PENDING

    def add_item(self, product, quantity):
        if self.status != OrderStatus.PENDING:
            raise ValueError("只能向待处理订单添加商品")
        self.items.append(OrderItem(product, quantity))

    def calculate_total(self):
        return sum(item.subtotal() for item in self.items)
Enter fullscreen mode Exit fullscreen mode

2. 应用层(Application Layer)—— 业务流程编排

应用层协调领域对象完成用例:

  • 接收来自表现层的请求
  • 调用领域层的业务逻辑
  • 管理事务和跨领域操作
# 应用层示例:创建订单用例
class CreateOrderUseCase:
    def __init__(self, order_repository, event_publisher):
        self.repository = order_repository
        self.event_publisher = event_publisher

    def execute(self, create_order_dto):
        # 1. 创建订单实体
        order = Order(
            order_id=generate_id(),
            customer=create_order_dto.customer
        )

        # 2. 添加商品(领域逻辑)
        for item in create_order_dto.items:
            order.add_item(item.product, item.quantity)

        # 3. 持久化
        self.repository.save(order)

        # 4. 发布领域事件
        self.event_publisher.publish(OrderCreatedEvent(order))

        return order.id
Enter fullscreen mode Exit fullscreen mode

3. 表现层(Presentation Layer)—— 对外接口

处理用户交互和外部系统调用:

  • REST API 控制器
  • GraphQL 解析器
  • CLI 命令处理器
  • DTO/VO 转换
# 表现层示例:FastAPI 控制器
class OrderController:
    def __init__(self, create_order_use_case):
        self.use_case = create_order_use_case

    @post("/orders")
    def create_order(self, request: CreateOrderRequest):
        dto = CreateOrderDTO(
            customer=request.customer_id,
            items=request.items
        )
        order_id = self.use_case.execute(dto)
        return {"order_id": order_id, "status": "created"}
Enter fullscreen mode Exit fullscreen mode

4. 基础设施层(Infrastructure Layer)—— 外部依赖

实现与其他系统的集成:

  • 数据库持久化(Repository 实现)
  • 第三方API调用
  • 缓存实现
  • 消息队列
# 基础设施层示例:SQLAlchemy Repository
class SQLAlchemyOrderRepository(OrderRepository):
    def __init__(self, session):
        self.session = session

    def save(self, order):
        db_order = OrderModel(
            id=order.id,
            customer_id=order.customer.id,
            total=order.calculate_total(),
            status=order.status.value
        )
        self.session.add(db_order)
        self.session.commit()
Enter fullscreen mode Exit fullscreen mode

依赖规则:整洁架构的生命线

关键原则:依赖只能从外向内,不能从内向外。

外层 → 内层(依赖方向)
内层 ← 外层(绝对不能依赖)
Enter fullscreen mode Exit fullscreen mode

这意味着:

  • 领域层不知道应用层、表现层或基础设施层的存在
  • 应用层只依赖领域层
  • 表现层和应用层都可以依赖领域层

依赖反转原则(DIP)

为了实现这个依赖规则,我们需要使用依赖反转

# 定义接口(领域层)
class OrderRepository(ABC):
    @abstractmethod
    def save(self, order): pass

    @abstractmethod
    def find_by_id(self, order_id): pass

# 实现接口(基础设施层)
class MySQLOrderRepository(OrderRepository):
    def save(self, order):
        # MySQL 实现
        pass

    def find_by_id(self, order_id):
        # MySQL 实现
        pass

# 应用层依赖接口,不依赖具体实现
class CreateOrderUseCase:
    def __init__(self, order_repository: OrderRepository):
        self.repository = order_repository
Enter fullscreen mode Exit fullscreen mode

整洁架构的实战好处

1. 单元测试变得简单

因为领域层不依赖外部世界,你可以直接测试业务逻辑:

def test_order_calculate_total():
    order = Order(order_id="1", customer=Customer("C1"))
    order.add_item(Product("P1", Money(100)), 2)
    order.add_item(Product("P2", Money(50)), 1)

    assert order.calculate_total() == 250
Enter fullscreen mode Exit fullscreen mode

不需要数据库、HTTP请求,只需要测试业务逻辑!

2. 易于替换实现

想从MySQL切换到PostgreSQL?只需要在基础设施层修改:

# 只需要修改这一处
class PostgreSQLOrderRepository(OrderRepository):
    # PostgreSQL 实现
    pass
Enter fullscreen mode Exit fullscreen mode

其他层完全不需要改动。

3. 团队协作更顺畅

不同团队可以并行工作:

  • 前端团队:先开发表现层,使用mock数据
  • 业务团队:先开发领域层
  • 基础设施团队:开发数据库、缓存等

常见误区

❌ 误区一:分层过度

不要创建太多层!四层足够了:领域、应用、表现、基础设施。

❌ 误区二:所有东西都要接口

只有需要被替换的依赖才需要抽象。简单的工具类不需要接口。

❌ 误区三:整洁架构只适合大型项目

恰恰相反!从小型项目开始使用整洁架构,可以避免项目成长后的重构痛苦。

总结

整洁架构不仅仅是一种架构模式,更是一种编程思想

  1. 把业务逻辑放在核心——这是你最宝贵的资产
  2. 依赖方向要统一——从外到内,永不逆流
  3. 接口隔离——只依赖你真正需要的东西
  4. 可测试性——业务逻辑应该能脱离任何外部依赖进行测试

记住:代码质量决定系统寿命。从今天开始,让你的代码变得整洁吧!


如果你觉得这篇文章对你有帮助,欢迎点赞、分享!也欢迎在评论区分享你的架构实践经验。

软件开发 #架构设计 #CleanArchitecture #整洁架构

Top comments (0)