我只是想弄清楚我是否想使用存储库模式。我能找到的三个优点是:
1. Testability (repositories can be injected into the controller)
2. Abstraction (complex eloquent queries can be refactored into repository functions)
3. Decoupling (enables me to replace the persistence layer)然而,除了第3点,我并没有清楚地看到这一点。
1. I can just as well inject the model (or a mock for testing)
2. I can also abstract the queries into functions and place them into the model instead of a repository.因此,假设我不关心与雄辩的关系,我不认为使用存储库有什么意义。我很感激任何能改变我主意的论点。
发布于 2017-10-20 23:48:54
从我的观点和经验来看,您可以使用雄辩作为存储库层。
对于第2点,您可以创建范围方法,以便能够与正常的雄辩查询一起使用。
$users = User::whereHasACarOfColor('yellow')->where('active, true)->get();
// ...
public function scopeWhereHasACarOfColor($query, $color)
{
return $this->whereHas(function ($cars) use ($color) {
return $cars->where('color', $color);
});
} 在过去的几个月里,我对Laravel中的存储层有着不同的体验:
getUsersWithYellowCars(),getUsersWithYellowCarsOrderedByName().另外,想说雄辩已经是一个ORM,如果您决定从MySQL更改为SQLite,您就不必更改代码中的任何内容。
发布于 2017-10-20 23:58:42
让我们逐一列出你的利益清单:
这是真的。在后面的问题中,您说您可以很容易地将一个模型注入到控制器中,那么这有什么意义呢?关键是,如果您使用一个接口来定义存储库方法,那么您可以在生产代码中使用具体的存储库来实际查询雄辩的模型,同时使用实现相同接口进行测试的“假”存储库。我经常这样做,我的“假”实现只是使用一个集合来保存我正在测试的模型。这样,您的测试运行得更快,并且不必担心控制器测试中的迁移。它还使您不必与单元测试中的数据库进行交互。--我并不是说对数据库进行测试本质上是不好的,但是您应该尽可能避免使用。使用存储库可以帮助您在不需要与数据库交互的情况下加快测试速度。通过在控制器中输入Repository接口,您可以传递一个假的实现来测试,并在生产代码的Service中绑定一个真正的实现。
这取决于你。Laravel中存储库模式的问题是,无论您多么努力地尝试,您的模型都绑定到数据库中。没有办法可以绕过它。扩展应用程序和重用存储库的可能性几乎为零,因此这并不一定是坏事。无论如何,业务逻辑不应该出现在您的模型或存储库中,因此您的应用程序的核心(如果设计得当)仍将从框架中抽象出来。在真正的存储库模式中,查询是在存储库中定义的。但是,由于Laravel的模型与数据库紧密耦合,所以您把这个逻辑放在哪里并不重要。事实上,Laravel有一些很好的口才特性,这可能会使您的模型中的逻辑变得更正确。在Laravel中,存储库是我在第一点中提到的,能够在测试中从数据库中抽象一些。
这是存储库模式的要点,也正是使第1点成为可能的原因。当然,传递雄辩的模型意味着无论模型在哪里,数据库也是如此。这只是你必须接受的活动记录。
扩展@Lloope的答案,另一个好处是将复杂的查询定义在一个位置(您的模型或存储库),以避免这样的代码散落在代码库中:
$professor->getStudents()->orderBy('name')->get();取而代之的是这样的用法:
$students = $usersRepository->getStudentsForProfessor($professor, 'name', 'ASC');在您的应用程序中编写出色的查询的问题是,随着需求的变化,您必须在应用程序中的任何地方更新这些查询。这可能只是在您的控制器一次,或在您的应用程序的几十个不同的部分。存储库上的getStudentsForProfessor方法(甚至仅仅是雄辩的模型)更易于维护。这意味着您的其他对象不需要担心getStudentsForProfessor做什么或者它是如何工作的。他们只是知道它将返回一组学生给给定的教授。存储库可以帮助您将查询逻辑组织在一个地方。一旦定义了这个接口或契约,其他对象就可以依赖它来执行它说的了。随着查询需求的变化,您可以在一个地方而不是在整个应用程序中更新实现。合同还是一样的。这比在任何地方编写有说服力的查询都灵活得多。
https://stackoverflow.com/questions/46857389
复制相似问题