分层架构中,服务层(Service Layer) 和 控制层(Controller Layer) 的区别

在分层架构中,服务层(Service Layer)控制层(Controller Layer) 虽然都涉及业务逻辑的处理,但它们的职责和定位有本质区别。

一句话概括:

  • 控制层(Controller):是 HTTP 请求的“入口”和“出口”,负责协议层逻辑

  • 服务层(Service):是业务逻辑的“发动机”,负责实现核心业务规则
     控制器仅做路由转发。服务层统一处理业务。两者分工明确,共同构建高可维护性的应用架构。


1. 职责划分

控制层(Controller)服务层(Service)
处理 HTTP 请求/响应 的交互逻辑处理 核心业务逻辑 的实现与协调
解析请求参数、验证输入格式(如 Pydantic)实现具体的业务规则(如订单创建、审批流程)
调用服务层方法并格式化返回结果协调多个模型(Model)或外部服务(如数据库、API)
处理路由、权限校验、异常捕获管理事务(如数据库原子操作)
不直接操作数据库或外部服务可被多个控制器或其他服务复用

2. 代码示例对比

控制层(Controller)
# app/api/v1/apis/workflow.py
from fastapi import APIRouter, Depends, HTTPException
from app.services.workflow import WorkflowService

router = APIRouter()

@router.post("/process/start")
async def start_process(
    biz_type: str, 
    biz_id: int,
    user: User = Depends(get_current_user),  # 权限校验
    service: WorkflowService = Depends()     # 依赖注入服务层
):
    # 参数校验(简单示例)
    if biz_type not in ["leave", "expense"]:
        raise HTTPException(400, "无效的业务类型")
    
    # 调用服务层核心逻辑
    try:
        instance = await service.start_process(biz_type, biz_id, user.id)
        return {"process_id": instance.id}  # 格式化响应
    except InsufficientPermissionError as e:
        raise HTTPException(403, str(e))    # 捕获服务层异常并转换
服务层(Service)
# app/services/workflow.py
from app.models.workflow import ProcessInstance
from app.models.user import User
from app.core.db import atomic_transaction

class WorkflowService:
    async def start_process(
        self, 
        biz_type: str, 
        biz_id: int, 
        user_id: int
    ) -> ProcessInstance:
        # 业务规则校验(示例)
        user = await User.get(id=user_id)
        if not user.has_permission("PROCESS_START"):
            raise InsufficientPermissionError("用户无权操作")
        
        # 数据库事务管理
        async with atomic_transaction():
            # 调用其他服务或模型
            process_id = await self.engine.start_process(biz_type, biz_id)
            instance = await ProcessInstance.create(
                process_id=process_id,
                biz_type=biz_type,
                biz_id=biz_id,
                status="RUNNING"
            )
        
        # 触发后续业务逻辑(如通知)
        await self.notify_approvers(instance)
        return instance

3. 关键区别

维度控制层服务层
输入来源HTTP 请求参数、Headers、Cookies方法参数(来自控制器或其他服务)
输出目标HTTP 响应(JSON/XML)返回业务对象(如 ORM 模型、DTO 对象)
依赖关系依赖服务层依赖模型层、工具类、外部服务(如 Perfect)
复用性通常不可复用(绑定特定路由)高度可复用(多个控制器/任务可调用)
单元测试重点请求解析、响应格式、异常转换业务规则、事务一致性、外部服务交互

4. 常见错误

❌ 控制层做业务逻辑
# 错误示例:在控制器中直接操作数据库
@router.post("/process/start")
async def start_process(...):
    # 直接操作数据库(破坏分层原则)
    instance = await ProcessInstance.create(...)
    await send_email(...)  # 直接调用通知
✅ 正确分层
# 控制器仅做路由转发
@router.post("/process/start")
async def start_process(...):
    return await service.start_process(...)  # 业务逻辑交给服务层

# 服务层统一处理业务
class WorkflowService:
    async def start_process(...):
        # 业务逻辑集中在此
        instance = await ProcessInstance.create(...)
        await self.notify_approvers(...)

5. 分层架构的优势

  1. 解耦性:控制器不关心业务实现,服务层不关心 HTTP 细节。

  2. 可测试性:服务层可脱离 Web 框架单独测试(如用 pytest 直接调用)。

  3. 复用性:一个服务可被多个控制器(甚至 CLI 命令行)复用。

  4. 维护性:业务逻辑集中管理,修改时无需搜索分散的控制器代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值