正确的方法(tm)在Symfony2 / Doctrine中使用实体和存储库

时间:2015-03-16 16:34:54

标签: php symfony doctrine-orm doctrine

好的,所以这是不是特定的“我做错了什么”编码问题,抱歉。如果它更适合其他堆栈*网站之一,请告诉我。

今天我被一个承包演出解雇了,他们正在使用Symfony2和Doctrine。我是一名高级程序员,但在这两个框架中都不是很有经验 - 尽管我确信我能够快速起步和跑步。毕竟,它是PHP - 可能出错?< / cynicism>

我指定的队友(作为“Symfony专家”,因此我起初非常乐意观看和学习)坚持认为'实体应该是不可变的,所有自定义业务逻辑应该进入存储库'。阅读文档(入门指南,不能少)这似乎是不真实的 - 存储库是针对“自定义getter”的,但数据操作是在实体中进行的(Doctrine代表模型)。对我来说很有意义(数据库无法知道bitflag 1是否意味着'活跃'和2'确认电子邮件'),但这个家伙是adament。当我按下一个例子来说明我应该如何在存储库中添加自定义数据编辑方法时(因为我愚弄了一段时间但是无法让Symfony看到它们而不经过箍并手动用存储库替换实体),他发送了一个代码示例实现或多或少的手动更新查询。 那么为什么要首先使用ORM?

他还反复声明,人们不应该触摸实体,因为更改可能会在重新生成时被覆盖。除了Doctrine似乎通常假设你编写实体并从那些生成数据库方案这一事实 - 而不是相反 - 除非我对英语的知识神秘失败,手册似乎清楚地说明了(重新)生成实体,现有的方法是独立的,所以它是完全安全的。

故事结束时,客户决定我们不能一起工作并选择另一个人。他们也有这种奇怪的论证,我是“项目中最昂贵的人”而我“没有提供足够的资历”。我确实指出,告诉别人他们是完全错的并且为此而大喊大叫(真实的故事,好吧,他们输入的所有大写字母在我的书中大喊大叫)也不会让我很开心,所以这就是那 - 我祝他们好运,我们分道扬..

我在这里失去理智吗?我错过了一些明显的东西吗?或者另一个人是否被误导(我当前的工作理论)关于什么属于实体和存储库中的什么?任何在Doctrine / Symfony护理方面有经验的人都要详细说明?我很乐意提供我们应该建立的更具体的例子。我非常好奇地学习在这些框架中做事的“正确方式”(tm)(为了将来的参考,它们还没有引起我的胃口),如果确实有更好的方法来消除模型代码来自实体。

1 个答案:

答案 0 :(得分:2)

Symfony2旨在让您选择回答这些问题的方式。它的结构是模块化的,允许您只选择和使用您需要的组件。有许多常见的设计模式,但显然团队需要选择一个并坚持下去。如果你们不能这样做,你可能不会尝试一起完成一个项目。

我认为在Symfony2中保持实体和控制器尽可能稀疏且易于阅读是一种很好的做法。我几乎什么都没有放在没有构建查询并运行它们的存储库中。几乎所有其他东西都应该是这种或那种服务。如何在服务之间强制分离关注点,这是开发团队的一项练习。

这篇文章讨论了一组常见的设计模式: http://www.ricardclau.com/2012/02/where-is-the-model-in-symfony2-entities-repositories-and-services/

在掌握如何做事以及在哪里放置细节时要考虑的另一个好处是通过一些核心/大型symfony包,看看他们放置的东西以及不同的组织风格为不同的目的而有意义(有些人比其他人更好)。

他的具体要求:

1)实体应该是不可变的

这似乎会导致您失去Doctrine的EntityManger和UnitOfWork提供的大部分功能。如果您仅使用手动查询更新它们,则必须重新加载实体以使它们与更新的DB状态相匹配。我想如果你想在请求开始时加载一个状态并且仅根据原始数据逐步处理对数据库的更新,这是有意义的。 (Doctrine确实在EntityManger中提供了将实体标记为只读的功能,以便不会保留对它们的更改。)

2)所有自定义业务逻辑都应该放在存储库中

在Symfony中,将“存储库”替换为“服务”,这几乎是100%正确的。存储库通常应该只包含可重复使用的复杂查询的代码,超出了Doctrine的findBy方法所能提供的代码。

3)他还反复声明,不应该触摸实体,因为更改可能会在重新生成时被覆盖。

真的......就覆盖而言。每当使用doctrine命令行工具从模式文件向实体添加更改时,都可能发生这种情况,从而进行备份。但是,该工具相当聪明,我没有看到我的任何更改被覆盖。

您的具体说法:

1)但是数据操作是在实体中进行的(Doctrine代表模型)

实体不是'MVC'中的'M',但通常只是存储状态的'M'的一部分。相关逻辑通常在表单,数据转换器,验证器和其他服务中保持独立。

2)他发送了一个实现或多或少的手动更新查询的代码示例。那么为什么要首先使用ORM?

即使您只通过手动查询而不是使用EntityManger更新数据,Doctrine还提供了许多其他优势:编程查询生成,输入清理,实体Hyrdation,查询/结果缓存,嵌套事务,ETC。

听到你的故事,这听起来像一个更高级的开发人员,与较低级别的开发人员一起工作,拥有更多的框架经验。我猜想其他开发人员从未在一个绿地Symfony2项目中独立/领导过,只是嘲笑他以前的高级开发人员做出的设计决策。

你们两个听起来都不是“正确”,你们两个都错了,因为你们陷入了一个必须由你们的客户裁决的争论中。也许如果你不那么热衷于表现自己,并且更愿意利用和探索你的伴侣的经验,深入研究他所倡导的实践背后的原因,你可能已经把它变成了成功......或者也许其他开发人员只是一个工具,你为自己节省了大量的压力和戏剧试图掩盖他的屁股:)