Laravel 存储库模式和多对多关系

Mil*_*Rey 3 ddd-repositories repository-pattern laravel-5

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

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

  1. $userRepository->getDashboardData($userId)。

2.$userRepository->getUser($userId)->withProjects()->withActiveSkills()->withReviews();

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

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

Sha*_*ool 5

您必须(例如)从面向对象的角度来决定返回的“用户”是否包含一系列技能。如果是这样,您返回的用户将已经拥有这些对象。

在使用常规对象的情况下,除非有很好的意义,否则尽量避免使用子实体。例如,“用户”实体负责确保子实体遵守业务规则。更喜欢使用不同的存储库根据任何其他标准选择其他类型的实体。

以这种方式谈论“关系”让我觉得您正在使用 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);
Run Code Online (Sandbox Code Playgroud)

或类似的东西。(只是在我的头顶打字)。

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

不仅很可能在没有 ORM“关系”功能的情况下进行编码..它通常更容易..你可以说这个功能增加了很多麻烦,因为 ORM 必须提供多少功能才能尝试减轻痛苦.

真的,有什么意义?它只是让您不必使用特定会员的 ID 来进行查找?也许我想循环处理大量不同的东西更容易?

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

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

这对我来说是设计系统的核心。问问自己……好吧,当我们有了新的用例时,我们必须做什么?如果答案是肯定的,确保我们的架构是这样的,我们只做这个和这个,我们真的不必搞乱其他的……那太好了!否则,答案可能更像是..我不知道..我想修改所有内容并希望它有效。

有很多方法可以处理这些东西。但是,我建议避免使用大量复杂的工具来换取更简单的方法/解决方案。存储库是抽象数据持久性以允许单独测试的好方法。如果您想单独测试,请使用它。但是,我不确定我对 ORM 关系如何与对象模型一起工作的了解很多。

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

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

我不喜欢这些巨大的物体的想法,它们被设计成绝对是所有东西的容器。我更喜欢将对象分解成专门为用例设计的位。

但是,我在胡说八道。简而言之..

  1. 不要滥用 ORM 关系功能。
  2. 最好有多个专为用例设计的小对象,而不是几个可以做所有事情的大对象。

只有我的 2 美分。