我们在团队的 PHP 中使用 ORM,我在两个单独的项目中注意到,即使我们专门详细讨论了良好的 MVC 设计,ORM 似乎允许人们从视图中进行数据库查询层和创建难以维护的代码。
我倾向于这样一种观点,即 ORM 使得在程序员没有想到的情况下进行查询变得太容易了。通过将 ORM 对象返回到视图层,程序员实际上是在将数据库连接泄漏到不应该有它的层。
我在这里正确地考虑 ORM 吗?如果是这样,为什么它如此受欢迎?如果我没有正确考虑它,我应该如何解决这些问题?
我们在团队的 PHP 中使用 ORM,我在两个单独的项目中注意到,即使我们专门详细讨论了良好的 MVC 设计,ORM 似乎允许人们从视图中进行数据库查询层和创建难以维护的代码。
我倾向于这样一种观点,即 ORM 使得在程序员没有想到的情况下进行查询变得太容易了。通过将 ORM 对象返回到视图层,程序员实际上是在将数据库连接泄漏到不应该有它的层。
我在这里正确地考虑 ORM 吗?如果是这样,为什么它如此受欢迎?如果我没有正确考虑它,我应该如何解决这些问题?
我会说你没有正确地考虑它。ORM 本身并不会促进不良做法,至少不会以您体验它的方式。
ORM 是一个工具,就像任何其他框架、api 或其他任何东西一样,您可以正确使用它,也可以不正确使用它。
听起来问题更像是您团队中的开发人员对 MVC 模式没有清晰的理解。我首先要解决这个问题。
我认为 MVC 模式的一个常见问题是开发人员倾向于将视图和控制器用于他们不应该做的事情。原因可能有很多,但每当你使用这样的东西时,我相信问题通常始于类似于这个想法的东西:
“这么简单的小事,我就在这里做,在那里做没有意义。”
基本上,当试图解耦设计和业务逻辑时,总会有一些情况更容易实现一些实际上属于表示层的业务层的部分。这不一定意味着开发人员很糟糕,但它可能表明缺乏经验或懒惰。我知道我曾多次犯过这件事,比如在为 Android 开发时(虽然从来没有专业过:))。
尝试找出一些使用您注意到的一些不良做法的示例案例,并拥有某种编码道场,您作为一个团队可以使代码变得更好并正确实施,如果您有时间,请展示拥有属于它们的东西的实际好处。我强烈建议不要使用实际代码,除非您自己编写或负责该代码的开发人员可以接受在其他开发人员面前被破坏。但这显然取决于您公司的文化以及开发人员是否对这类事情感兴趣并持开放态度。我个人很想在我的工作场所拥有类似的东西。
我不知道在视图层中有小的 ORM 调用一定很糟糕。例如,我可能有foreach (Category::getAll() as $Category):
一个循环来列出页面上的类别。连接不会泄漏到视图的范围内(或者无论如何它当然不应该),因为它是由 ORM 封装的。我可以在控制器中分配这个调用的结果,并将对象数组传递给模板(我当然会使用更复杂的调用),但在视图中,imo 微不足道的情况很好。
根据我的经验,ORM 的最大问题是“n+1”数据库查询计数的增长。通常,屏幕上的一对多列表可以从单个查询中呈现,但是 ORM 使得对一个表使用主循环非常方便,然后对辅助表的每个实例进行单独的选择。这是低效的,但您只会注意到当您的数据库开始因为它必须处理的查询数量的增加而嘎嘎作响时。
最好的防范措施是让您的开发人员在开发模式下运行工具栏(例如 Symfony2 工具栏、PHP Debug 或类似工具),向他们显示构建屏幕所需的查询数量。当琐碎的屏幕开始需要超过 50 个查询(或您指定的任何上限)时,它们需要重构。
此外,值得选择具有合理表达查询语法的 ORM,否则您的开发人员将回避到“原始 SQL”模式,这会破坏首先使用 ORM 的一些原因。出于同样的原因 - Daniel 很好地说明了这一点 - 为您的开发人员提供有效使用 ORM 的培训是一个好主意。
从视图中进行查询是一种不好的做法。您可以这样做,但最好通过控制器通过 Ajax 请求或您认为合适的任何方式进行。