简化存储库模式和SOA

时间:2015-07-16 16:33:46

标签: laravel optimization architecture repository-pattern soa

我正在使用Laravel 5,但我认为这个问题可以应用于单一框架或语言的范围之外。最近几天,我一直在为存储库编写接口和实现,然后将服务绑定到IoC以及所有这些东西。感觉非常慢。

如果我需要在我的服务中使用新方法,比如说,Store::getReviews()我必须在我的实体模型类(数据源,在本例中为Eloquent)中创建关系,那么我必须在repo接口中声明方法使其成为任何其他实现所必需的,然后我必须在repo实现中编写实际的方法,然后我必须在服务上创建另一个方法,该方法调用repo来提取商店的所有评论...(故意的运行句子)感觉太多了。

现在创建一个新模型并不像扩展基础模型类那么简单。我必须编写和跟踪这么多文件。有时候我会对我应该放置什么东西感到困惑,或者找到一个方法,我会在错误的班级中找到一个方法。我在服务中也失去了Eloquent的查询功能。每当我需要Eloquent所拥有的东西时,我必须在回购和服务中实现它。

这个架构背后的想法很棒但是我发现的实际实现非常繁琐。 有没有更好,更快的方式做事?我觉得我太乱了,尽管我把常用的方法和东西放在抽象的课程中。写作太多了。

2 个答案:

答案 0 :(得分:2)

当我搬到Laravel 5时,我已经和所有这些东西搏斗了。那时我决定改变我的方法(it was tough decision)。在此过程中,我得出以下结论:

  1. 我决定放弃Eloquent(以及Active Record模式)。我甚至不使用查询构建器。我仍然使用DB fascade,因为它可以方便地用于参数化查询绑定,事务,日志记录等。开发人员应该知道SQL,如果他们需要知道它,那么为什么要强制另一个它们上的抽象层(一个不能完全或有效地替换SQL的层)。请记住,从OOP世界到关系数据库世界的桥梁永远不会很漂亮。跟我一起,继续读...
  2. 由于#1,我切换到Lumen,默认情况下关闭Eloquent。它快速,精益,并且仍然在Laravel中完成我需要和喜爱的一切。
  3. 每个查询都符合两个类别之一(我认为这是CQRS的一种形式):

    3.1。 存储库(命令):这些处理更改状态(写入)以及需要在更改状态之前对对象进行水合并应用某些规则的情况(有时您必须执行一些读取才能进行写入)(有时你也会进行批量写入和水合可能效率不高,所以只需创建执行此操作的存储库方法)。所以我有一个名为" Domain"的文件夹。 (对于域驱动设计)和内部是更多的文件夹,每个文件夹代表我对业务领域的看法。每个实体我都有一个配对的存储库。这里的实体是一个类似于其他人可能称之为" model"的类,它包含属性并且具有帮助我保持属性有效或者对它们起作用的方法,这些方法最终将保存在存储库中。存储库是一个包含许多方法的类,这些方法表示我需要做的与该实体相关的所有查询类型(即。$repo->save())。这些方法可以接受一些参数(允许在内部进行一些动态查询操作,但不能过多),并且在内部,您将找到原始查询和一些代码来实现水合。您会发现存储库通常接受和/或返回实体。

    3.2。 查询(a.k.a。屏幕?):我有一个名为" Queries"的文件夹。我有不同类的方法,里面有原始查询来执行显示工作。这些类只是帮助将事物分组,但与存储库不同(即它们不进行保湿,写入,返回实体等)。目标是将这些用于读取和大多数显示目的。

  4. 不必要地接口。接口适用于需要它们的多态情况。您知道的情况将在多个实现之间切换。当您以1:1工作时,它们是不必要的额外工作。另外,稍后上课并将其转换为界面很容易。你永远不想过早地过度优化。
  5. 由于#4,您不需要很多服务提供商。我认为为我的所有存储库提供服务提供程序会有点过分。
  6. 如果您想要切换数据库引擎几乎是神话般的时间,那么您所要做的就是去两个地方。上面#3中提到的两个地方。您替换里面的原始查询。这很好,因为您有一个应用程序所需的所有持久性方法的列表。您可以在这些方法中定制每个原始查询,以便以数据存储所要求的独特方式使用新数据存储。该方法保持不变,但内部查询发生了变化。重要的是要记住,更改数据库所需的工作显然会随着应用程序的增长而增长,但应用程序的复杂性必须在某处。每个原始查询代表复杂性。但是您已经封装了这些原始查询,因此您已经尽最大努力屏蔽了应用的其余部分!
  7. 我成功地使用了受DDD概念启发的这种方法。一旦您使用存储库方法,那么几乎不需要使用Eloquent IMHO。而且我发现我没有写出额外的东西(正如你在问题中提到的那样),同时仍然保持我的应用程序灵活应对未来的变化。这是来自工匠的另一个approach(虽然我不一定同意使用Doctrine ORM)。好运和快乐的编码!

答案 1 :(得分:-1)

Laravel的Eloquent是一项活跃的记录,这项技术需要大量的处理。域实体被理解为普通对象,为此目的尝试使用Doctrime ORM。我建立了一个使用Lumen的辅导员,并且教学ORM遵循这个链接。

https://github.com/davists/Lumen-Doctrine-DDD-Generator

*对于acured perfomance analisys有cachegrind。

http://kcachegrind.sourceforge.net/html/Home.html