HandlersServicesrepositorymodels
三层模式(真实项目的干净架构)
在构建可扩展的后端系统(API、机器人、Web 应用程序)时,我们将职责分层。
为什么?
因为将所有内容混合在一个文件中会导致:
- 意大利面条代码
- 硬调试
- 硬测试
- 硬缩放
- 客户改变需求时的痛苦
所以我们使用:
什么是三层模式?
它是一种代码组织结构,将应用程序分为三个逻辑层:
1.处理层(表示层)
2.服务层(业务逻辑层)
3. 存储库层(数据层)
每一层都只有一个职责。
简单的想法。强大的影响力。
为什么需要它?
想象一下您的 OMR Streamlit 应用程序。
如果您:
- 检测图像
- 分析答案
- 转换为 JSON
- 存储在 MongoDB 中
- 返回响应
全部都在一个函数内……
现在客户说:
“存储在 PostgreSQL 而不是 Mongo 中。”
现在你必须修改一切😵
但如果你使用图层:
- 仅存储库层发生变化。
- 应用程序的其余部分保持不变。
这就是清洁工程。
它解决了什么问题?
| 无层 | 分层 |
|---|---|
| 乱码 | 清洁分离 |
| 调试困难 | 轻松调试 |
| 难以测试 | 简单的单元测试 |
| 紧耦合 | 松耦合 |
| 改变打破一切 | 更改仅影响一层 |
该模式解决了:
- 可维护性问题
- 可扩展性问题
- 测试问题
- 代码可读性问题
第 1 层:处理程序(看门人🚪)
这是什么?
Handler 是应用程序的入口点。
它讲述的是:
- HTTP 请求
- 流线型用户界面
- 电报消息
- REST API 调用
它理解:
- JSON
- HTTP
- 状态代码
- 用户输入
它到底有什么作用?
它:
- 解析 JSON → 转换为 Python 字典
- 验证输入
- 调用服务层
- 返回 HTTP 响应
它不:
- 直接与数据库对话
- 包含业务逻辑
- 执行繁重的计算
示例(登录 API)
1 |
|
第一层:服务(应用程序的大脑)
什么是服务层?
服务层是应用程序的一部分,包含核心业务逻辑。
它负责:
- 做出决定
- 应用业务规则
- 协调工作流程
- 调用存储库
- 调用外部服务(电子邮件、付款等)
它不处理:
- HTTP
- JSON解析
- 状态代码
- 用户界面渲染
服务层只关注系统应该做什么,而不关注请求如何到达。
为什么需要服务层?
没有服务层:
- 业务逻辑在控制器内部混合。
- 代码变得混乱且紧密耦合。
- 测试变得困难。
- 逻辑不能在不同环境中重用。
服务层确保:
- 干净的架构
- 可重复使用性
- 可维护性
- 可扩展性
- 简单的单元测试
它解决了什么问题?
Service层解决:
1️⃣ 关注点分离
将业务逻辑与 HTTP 或 UI 逻辑分开。
2️⃣ 可重复使用性
以下人员可以使用相同的服务:
- 休息API
- 电报机器人
- CLI 脚本
- 后台工作者
- 计划任务
3️⃣ 可测试性
您可以在不运行 Web 服务器的情况下测试业务逻辑。
4️⃣ 可维护性
如果业务规则发生变化,只需要修改服务层。
🔄 工作原理(流程示例)
示例:课程购买系统
客户发送购买课程的请求。
步骤 1️⃣ 控制器接收请求
- 解析 JSON
- 验证输入
- 调用服务层
1 | purchase_service.buy_course(user_id, course_id, payment_token) |
第 3 层:存储库层(数据访问层)
什么是存储库层?
存储库层 负责处理与数据库的所有交互。
该层:
- 执行 SQL/NoSQL 查询
- 从数据库中获取数据
- 插入新记录
- 更新现有记录
- 删除记录
- 将数据库行/文档映射到应用程序对象
它充当应用程序和数据库之间的桥梁。
存储库不包含业务逻辑。
它只处理数据持久性。
为什么需要存储层?
没有存储库层:
- 数据库查询分散在控制器和服务中。
- 代码与特定数据库紧密耦合。
- 更改数据库变得很痛苦。
- 测试变得困难。
存储库层确保:
- 清晰的关注点分离
- 数据库抽象
- 更轻松的数据库切换
- 更好的可维护性
- 测试中更容易模拟
它解决了什么问题?
1️⃣ 防止控制器中的数据库逻辑
控制器不应编写 SQL 查询。
2️⃣ 防止服务中的数据库逻辑
服务应该关注业务规则,而不是 SQL 语法。
3️⃣ 减少紧耦合
如果明天你从 MongoDB 切换到 PostgreSQL,
仅存储库发生变化。
4️⃣ 提高可测试性
您可以在测试期间模拟存储库方法,而无需真正的数据库。
存储库到底有什么作用?
存储库:
- 运行数据库查询
- 将原始数据库数据转换为可用对象
- 处理低级数据访问逻辑
- 将干净的数据返回给服务层
它不:
- 应用业务规则
- 处理HTTP
- 验证请求输入
- 格式化 API 响应
工作原理(流程示例)
示例:用户登录系统
步骤 1️⃣ 控制器接收请求
- 解析 JSON
- 通话服务
1 | auth_service.login(email, password) |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 xhj的博客!