4

具体问题

我有一个操纵一些公司(实体)的对象 A(一个实体),公司可以链接在一起(例如,如果他们有一些共同的股东)。我希望 A 能够知道公司 C1 是否与公司 C2 相关联。

情怀

在我的知识和习惯状态下,我认为公司实体中应该有一种方法来判断它是否与另一个实体相关(第 1 点)。当然,我可以通过获取所有公司联系来做到这一点,并查看我的公司 C2 是否在那里(第 2 点)。但这很脏,这意味着出于什么原因获得所有依赖项?获得一个可以从数据库中轻松检索的布尔值,我可以考虑在与公司链接的存储库中创建一个函数(第 3 点)。但是不,因为实体(A 或 C1 和 C2)中没有可用的东西,所以轻量级对象会记住。

论据

  • 第 1 点基于单一职责原则。随意批评这一点。由于实体应该嵌入模型逻辑,我认为 isConnectedWith 函数应该在 CompanyEntity 的定义中是正确的。请记住这里 A 也是一个实体(所以这里也是存储库)
  • 第 2 点是一个解决方案,它在某种意义上是好的:这是正确的做法,如果,那是一个很大的如果,Doctrine 只是模拟的是真的;如果只是调用$object->connexions访问了内存中某处已经存在的某些对象集合。但事实很糟糕:它不存在,它存在于我们 webapp 的常见瓶颈:数据库。
  • 第 3 点我厌倦了 Data Mapper & Dependency Injection 组合告诉你的实体(和一些存储库)应该只靠它们自己存在,因为它们是模型逻辑。也许我的理解非常错误,但是由于每个人都说这是一件坏事,所以我完全放弃了在实体中注入帮助器或配置的想法。

问题

您将如何解决保持完整性和性能并避免肮脏的解决方法的问题?我的论点有哪些不好的地方?

4

1 回答 1

4

来分析一下你的观点

第 3 点

第3点根本不是解决方案!谁说将几乎所有东西都注入实体不是一个好的解决方案,这是绝对正确的。这几乎是 OO 和模式编程最佳实践的“标准事实”。
实体用于表示“对象”(当然不是在 IT 接受中!)因此,属性和访问器方法是您必须包含的唯一内容。
考虑一下您注入的东西可能会随着时间而改变的情况(方法签名、方法返回类型或逻辑):在这种情况下,您必须更改实体本身以保持事物一起工作,但为什么必须这样做实体,没变?深入思考它,因为它是面向对象编程的一个很好的起点(不仅仅是 symfony2 或实体表示!)

第 2 点

是的,你是对的:为什么要从数据库中获取所有实体,或者,如果你写了一个“好”的查询,那么只有你正在搜索的实体,如果你永远不会使用它?
关于这一点,您必须分析以下内容:

  • 我是否要在其他地方使用这个(或那些)实体,所以获取它可能会很好?
  • 我是否知道 Doctrine2 将保存在他获取对象(*)的内存中?这意味着,当您查询(或询问)之前获取的同一个对象时,他会返回给您该对象的同一个实例?因此,没有数据库连接,没有 fecth,没有重量级操作。

第 1 点

是的,这是一个很好的观点。您必须实现(当然是在存储库中!)类似->isThere()或更好的方法(这是想到的名字)。
使用这种方法,您可以编写自定义 SQL(称为D QL,其中D代表 Doctrine),其中您只返回一个标志或一个整数(通过COUNT(*)类似的聚合函数获得)。
对于获取的不是ArrayCollection实体而是标量结果,顾名思义,使用$query->getSingleScalarResult();
我想我会倾向于最后一个解决方案。

希望已经解释得很好


(*) 这称为恒等映射

于 2013-03-01T09:26:12.130 回答