在 MVC(Model-View-Controller)架构中,Model(模型) 是整个系统的核心和基石。它主要负责数据的获取、处理、业务逻辑以及状态管理。
很多人容易把 Model 仅仅理解为“数据库表”,但实际上它的职责要丰富得多。以下是 Model 的核心用法与最佳实践:
1. Model 的核心职责
* 数据访问(Data Access):负责与数据库(或缓存、第三方 API)进行交互,执行 CRUD(增删改查)操作。
* 业务逻辑(Business Logic):处理数据的规则和验证。例如:用户注册时密码的哈希加密、订单创建时库存的扣减计算等。
* 数据封装(Data Representation):将底层的数据结构封装成易于在系统中传递的对象,而不是直接暴露原始的数据库查询结果。
2. Model 的常见用法模式
在实际开发中,Model 通常有以下几种设计模式:
① 贫血模型(Anemic Model / 数据访问对象 DAO)
* 用法:Model 仅仅是一个数据结构(如只包含字段和 Getter/Setter),所有的业务逻辑都写在 Controller 或 Service 层。
* 适用场景:简单的 CRUD 项目、快速原型开发。
* 缺点:Controller 会变得极其臃肿,业务逻辑分散,难以复用和测试。
② 充血模型(Rich Domain Model)
* 用法:Model 既包含数据,也包含与这些数据强相关的业务行为。例如,User 模型中不仅有 name 和 email 字段,还有 changePassword() 或 hasActiveSubscription() 等方法。
* 适用场景:业务逻辑复杂、领域驱动设计(DDD)的项目。
* 优点:高度内聚,业务规则集中,易于单元测试。
③ 活跃记录模式(Active Record)
* 用法:Model 既包含数据,又包含数据库操作方法和部分业务逻辑。例如:user = new User(); user->name = 'test'; user->save();
* 代表框架:Ruby on Rails, Laravel (Eloquent), ThinkPHP。
* 优点:开发极其迅速,代码直观。
* 缺点:当业务逻辑极其复杂时,Model 会变得非常庞大。
④ 数据映射模式(Data Mapper)
* 用法:Model 是纯粹的业务对象,不包含任何数据库操作。通过一个独立的 Mapper(如 Repository 或 ORM)来负责 Model 与数据库之间的转换。
* 代表框架:Java (Hibernate), Doctrine (PHP)。
* 优点:Model 与数据库完全解耦,非常适合复杂的业务逻辑和单元测试。
3. 代码示例对比
❌ 错误用法(把逻辑全写在 Controller 里):
✅ 正确用法(将逻辑下沉到 Model 或 Service 中):
4. 黄金法则(避坑指南)
1. Model 绝不依赖 View:Model 中绝对不能出现 HTML、JSON 序列化(除非是专用的 Resource/DTO)或 HTTP 响应代码。
2. Model 尽量不依赖 Controller:Model 应该是独立可测试的。
3. 保持单一职责:如果 UserModel 里不仅有用户登录逻辑,还有发送博客文章的逻辑,那就应该拆分。
4. 善用 Service 层:如果一个业务操作需要同时调用 UserModel、OrderModel 和 EmailService,请把这些逻辑放在 Service 层,而不是硬塞进某一个 Model 里。