Skip to content

Latest commit

 

History

History
58 lines (42 loc) · 2.95 KB

File metadata and controls

58 lines (42 loc) · 2.95 KB
name metaframe-active-record-pattern
category engineering
description 活动记录模式 | Code & Engineering

活动记录模式

英文名: Active Record Pattern
分类: 编码实践
作者: Martin Fowler, 2002
复杂度: beginner
成熟度: established
AI 相关: ❌ 否

简介

将数据库行封装并在对象内部实现 CRUD 逻辑的领域对象模式

核心概念

  • 每类一表映射:每个活动记录类直接映射到一张数据库表,无需中间映射层
  • 自包含持久化:领域对象拥有自己的 SQL 或查询构建器调用,无需独立的 DAO 或仓储类
  • 生命周期回调:在创建、更新、删除事件时自动触发的钩子,使验证和审计等横切关注点驻留在模型上
  • 查询方法:类级别查询方法返回预填充对象,将 SQL 封装在友好的领域 API 之后
  • 约定优于配置:命名约定(复数表名、id 主键)消除了样板映射配置

使用步骤

  1. 将类映射到数据库表:每个类属性对应一列,每个实例代表该表中的一行
  2. 在对象上内嵌持久化方法:直接在领域类上实现 save()、find()、update() 和 delete(),调用方无需直接接触 SQL
  3. 使用类级别查询方法:暴露 User.findByEmail() 等静态或类方法,将其转换为 SQL SELECT 并返回填充好的对象
  4. 利用生命周期回调:在类上挂载 before_save、after_create 等回调,以强制验证、时间戳和副作用
  5. 随代码一起迁移模式变更:将数据库迁移文件版本化并置于模型文件旁,使模式与行为同步演进

适用场景

['构建以 CRUD 为主、领域逻辑较薄且紧密映射数据库模式的应用', '快速原型或中小型 Web 应用,开发速度优先于架构纯粹性', '希望用单一内聚对象同时充当领域模型和持久化层、无需独立仓储层的团队', '使用约定优于配置框架(如 Rails 或 Laravel)且 Active Record 是惯用方法的应用']

最佳实践

✅ 推荐做法

  • 对于领域模型与表结构高度一致的直接 CRUD,使用活动记录
  • 利用生命周期回调进行验证和自动时间戳管理,而非在服务层重复逻辑
  • 依赖框架提供的迁移工具跨环境保持模式与模型同步
  • 添加作用域或命名查询方法封装常用过滤条件,而非将裸查询分散在代码库中

❌ 避免做法

  • 不要在具有丰富业务规则的复杂领域中使用活动记录——持久化与行为的耦合会成为维护负担
  • 不要在生命周期回调中编写业务逻辑,因为这对调用方不可见且难以独立测试
  • 不要将活动记录对象作为 DTO 跨服务边界共享,因为这会泄漏持久化细节,导致模式变更意外级联
  • 不要让模型积累数百个方法——当模型超出单一职责时,改用服务对象或数据映射器

Sources: SDFrame (Software Design) MetaFrame: 💻 Code & Engineering / 编码与工程