repository 模式是分层 php 项目中隔离持久化逻辑的刚需,通过接口(如 userrepositoryinterface)统一数据访问契约,配合依赖注入容器实现可替换性,确保业务层不感知数据来源。

Repository 模式在 PHP 中不是“锦上添花”,而是分层项目里避免持久化逻辑污染业务层的刚需。它和工厂模式配合时,关键不在“创建对象”,而在把「数据怎么来」和「数据怎么用」彻底断开。
Repository 解决的是职责越界问题
很多 PHP 项目里,Controller 或 Service 直接调用 User::find()、Order::where()->get(),看似简洁,实则埋下三类隐患:
- 业务逻辑强依赖 Eloquent 或原生 PDO,换数据库驱动或迁移到 NoSQL 时要改遍所有服务类
- 测试时无法干净地 mock 数据来源,只能走真实数据库或打桩整个模型,速度慢、不稳定
- 分页、缓存、预加载等数据访问策略散落在各处,修改一处可能漏掉另一处
Repository 把这些收束到一个接口里,比如 UserRepositoryInterface,让上层只跟「用户集合」打交道,不关心它是从 MySQL 查的、Redis 缓存读的,还是从 API 同步来的。
工厂模式不是用来 new Repository 的
常见误区是写个 RepositoryFactory::make('User'),然后返回具体实现——这反而增加了一层无意义的间接性。现代 PHP 项目应由依赖注入容器(如 Laravel 的 Container、PHP-DI)管理 Repository 实例:
- 接口绑定到实现:
$container->bind(UserRepositoryInterface::class, DatabaseUserRepository::class) - 需要切换为内存或 Mock 实现时,只需改绑定,不碰业务代码
- 若需运行时选型(如按租户切换数据源),才在工厂里封装逻辑,但工厂本身也应被容器管理,而非静态方法
例如:一个支持多租户的 TenantAwareUserRepository 构造时接收 TenantResolver,而不是在 create() 里硬编码 new 判断逻辑。
Repository 和工厂真正协同的点在“可替换性”
两者组合的价值,体现在你能在不改一行业务代码的前提下,完成以下切换:
- 开发环境用
InMemoryUserRepository,跳过数据库启动更快、更隔离 - 集成测试用
FakeUserRepository,预设固定数据集,断言更稳定 - 灰度发布时,让部分请求走
ApiUserRepository(调用微服务),其余走DatabaseUserRepository
这种灵活性的前提,是 Repository 接口足够窄、契约清晰,且工厂(或容器)不把构造细节泄露给调用方。一旦你在 findById() 方法里塞进缓存 key 拼接或日志埋点,这个接口就不再纯粹,后续替换成本会指数上升。
最容易被忽略的一点:Repository 接口方法名必须反映领域语义,而不是 SQL 动作。用 findActiveByTeamId(),别用 findByTeamIdAndStatus();前者可被不同实现自由优化(查库、查缓存、查搜索索引),后者直接锁死了参数结构和查询意图。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











