Laravel Repository模式与多对多关系

时间:2016-04-28 08:00:44

标签: laravel-5 repository-pattern ddd-repositories

在我们的新项目中,我们决定使用六边形架构。我们决定使用存储库模式来获得更多的数据访问抽象。我们使用命令总线模式作为服务层。 在我们的仪表板页面中,我们需要大量数据,因此我们应该使用3级多对多关系(用户 - >项目 - >技能 - >审核),并且技能应该是活动的(状态= 1)。

问题出在这里,我应该把它放在哪里?

  1. $ userRepository-> getDashboardData($用户id)
  2. 2 $ userRepository->的getUser($用户id) - > withProjects() - > withActiveSkills() - > withReviews();

    3. $ user = $ userRepository-> getById();   $ projects = $ projectRepository-> getByUserId($ user-> id);  $ skills = $ skillRepository-> getActiveSkillsByProjectsIds($ projectIds);

    在这种情况下,我无法找到存储库模式的好处,除了编码到接口,这可以通过模型接口实现。 我认为解决方案3是完美的,但它增加了很多工作。

1 个答案:

答案 0 :(得分:1)

你必须从面向对象的角度决定(例如)" User"返回的是其中包含一系列技能的人。如果是这样,您返回的用户将已拥有这些对象。

在使用常规对象的情况下,尽量避免使用子实体,除非它很有意义。比如,例如.. '用户'实体负责确保子实体遵守业务规则。希望使用不同的存储库根据其他标准选择其他类型的实体。

谈论"关系"以这种方式让我觉得你使用ActiveRecord,因为否则他们只是孩子的对象。 "关系"存在于关系数据库中。如果你像AR一样混合数据库记录/对象,它只会爬进你的对象。

在使用ActiveRecord对象的情况下,您可能会考虑在存储库上使用特定方法来加载正确配置的成员对象。 $members->allIncludingSkills()或者其他什么。 这是因为您在返回多个实体时必须解决N + 1. 然后,您需要对结果集使用预先加载,并且您不想使用相同的预先加载每个请求的配置。因此,您需要一种方法来描述每个请求的配置。一种方法是在存储库中为不同的请求调用不同的方法。

然而,对我来说..我不想让一堆物体只有......无限的触及..例如..你可以拥有$member->posts[0]->author->posts[0]->author->posts[0]->author->posts[0]

我更喜欢把事情视为“平淡无奇”。尽可能。

$member = $members->withId($id);
$posts = $posts->writtenBy($member->id);

或类似的东西。 (只是打个招呼。)

没有人喜欢大量的嵌套数组,并且 ActiveRecord可以被滥用到其对象基本上是带方法的数组和无限嵌套的潜力。因此,虽然它可以是一种处理数据的便捷方式。我会努力防止滥用关系作为一个概念,并尽可能保持你的结构平坦。

如果没有ORM'关系,不仅可以进行编码。功能......它通常更容易..你可以说这个功能增加了很多麻烦,因为ORM必须提供多少功能才能减轻痛苦。

真的,重点是什么?它只是让你不必使用特定成员的ID来进行查找?也许我觉得更容易绕过很多不同的东西?

如果您希望能够单独测试代码,那么存储库在ActiveRecord案例中确实特别有用。否则,您可以使用Laravel的内置功能创建范围等,以防止在任何地方都需要冗余(并因此脆弱)的查询逻辑。

创建特定于UI的模型也是完全合理的。 您可以拥有多个使用相同数据库表的ActiveRecord模型,例如,您仅用于特定用户界面用例。仪表板例如。如果您有一个新的用例..您只需创建一个新模型。

这对我来说是设计系统的核心。问我们自己..好吧,当我们有一个新的用例时,我们将要做什么?如果答案是肯定的,那么我们的架构肯定是这样的,我们就这样做了,而且我们真的不得不把它们搞得一团糟......那太好了!否则,答案可能更像......我不知道......我猜想修改所有内容并希望它有效。

有很多方法可以解决这个问题。但是,我建议避免使用大量复杂的工具来换取更简单的方法/解决方案。存储库是一种抽象数据持久性的好方法,可以单独进行测试。如果要单独测试,请使用它。但是,我不确定我在ORM关系如何与对象模型一起销售方面做得很多。

例如,我们是否有一些包含以下内容的大量Member对象?

  • 该成员留下的所有评论
  • 会员拥有的所有技能
  • 该成员提出的所有建议
  • 所有朋友邀请会员发送
  • 该成员建立的所有朋友

我不喜欢这些大型物体的想法,这些物体只是容器,绝对是一切。我更喜欢将对象分解为专门为用例设计的位。

但是,我在漫无边际。简而言之..

  1. 不要滥用ORM关系功能。
  2. 最好有多个针对用例专门设计的小对象,而不是几个做大事的大型对象。
  3. 只需2美分。