7

最近由于 Rails 的流行,很多人开始使用 activerecord 作为模型。然而,在我听说 Rails 之前(我的同龄人小组不喜欢开源东西,我们在一所 .NET 学校接受过教育……),在我做最后一年的项目时,我发现了这个模型的定义

该模型代表企业数据以及管理对这些数据的访问和更新的业务规则。模型通常用作模拟真实世界过程的软件,因此在定义模型时应用简单的真实世界建模技术。

它并没有说模型应该像 activerecord 那样表示一个表。而且通常在一个事务中,一个人可能必须查询一些不相关的表,然后操作来自不同表的数据......所以如果使用 activerecord 作为模型,那么任何一个都必须将所有逻辑代码塞进控制器(这是在某些 php 框架中有点流行),这使得测试或破解 activerecord 模型变得困难,因此它不仅对它映射到的表执行数据库操作,而且还对其他相关表执行数据库操作......

那么,滥用(恕我直言)activerecord 作为 MVC 架构模式中的模型有什么好处呢?

4

3 回答 3

8

Martin Fowler 在 Patterns of Enterprise Application Architecture 中描述了这种模式以及其他两种模式或架构。这些模式适用于不同的情况和不同程度的复杂性。

如果你只想简单的东西,你可以使用事务脚本。这是您在许多旧的 ASP 和 PHP 页面中看到的架构,其中单个脚本包含业务逻辑、数据访问逻辑和表示逻辑。当事情变得更复杂时,这很快就会崩溃。

您可以做的下一件事是在演示文稿和模型之间添加一些分离。这是活动记录。该模型仍然与数据库相关联,但您拥有更多的灵活性,因为您可以在视图/页面/任何内容之间重用您的模型/数据访问。它没有它应有的灵活,但取决于您的数据访问解决方案,它可以足够灵活。.Net 中的 CSLA 等框架有很多方面来自这种模式(我认为 Entity Framework 看起来也有点像这样)。它仍然可以处理很多复杂性而不会变得不可维护。

下一步是分离数据访问层和模型。这通常需要一个好的 OR 映射器或大量工作。所以不是每个人都想走这条路。许多诸如领域驱动设计之类的方法都采用了这种方法。

所以这都是上下文的问题。你需要什么,什么是最好的解决方案。我什至有时仍将事务脚本用于简单的一次性代码。

于 2008-09-11T13:50:52.810 回答
2

我多次说过,使用 Active Record(或几乎相同的 ORM)作为业务模型并不是一个好主意。让我解释:

PHP 是开源的、免费的(以及所有长篇故事……)这一事实为它提供了一个庞大的开发人员社区,他们将代码倒入论坛、GitHub 等网站、Google 代码等。您可能认为这是一件好事,但有时它往往不是“那么好”。例如,假设您正面临一个项目,并且您希望使用 ORM 框架来解决用 PHP 编写的问题,那么……您将有很多选项可供选择

  • 教义
  • 推进
  • QCodo
  • 麻木
  • 红豆

这样的例子不胜枚举。定期创建新项目。所以想象一下,你已经构建了一个完整的框架,甚至是一个基于该框架的源代码生成器。但是您没有安排商务课程,因为毕竟“为什么要再次编写相同的课程?”。随着时间的推移,一个新的 ORM 框架发布了,您想切换到新的 ORM,但是您必须使用直接引用您的数据模型来修改几乎每个客户端应用程序。

归根结底,Active Record 和 ORM 应该位于应用程序的数据层中,如果将它们与表示层混合使用,您可能会遇到像我刚刚放置的这个示例一样的问题。

听听@Mendelt 的话:阅读 Martin Fowler。他发表了许多关于 OO 设计的书籍和文章,并发表了一些关于该主题的好材料。此外,您可能想查看Anti-Patterns,更具体地说是Vendor Lock In,当我们使我们的应用程序依赖于 3rd 方工具时会发生这种情况。最后,我写了这篇博客文章,谈到了同样的问题,所以如果你愿意,请查看。

希望我的回答对你有用。

于 2010-11-24T03:00:01.270 回答
1

在 MVC 中使用 Rails ActiveRecord 作为模型的好处在于它为您提供了自动 ORM(对象关系映射器)和在模型之间创建关联的简单方法。正如您所指出的,有时可能缺少 MVC。

因此,对于涉及许多模型的复杂事务,我建议在控制器和模型之间使用 Presenter(Rails Presenter Pattern)。Presenter 将聚合您的模型和事务逻辑,并保持易于测试。您肯定希望努力将所有业务逻辑保留在您的模型或演示器中,并保留在您的控制器(Skinny Controller、Fat Model)之外。

于 2008-09-11T14:09:08.947 回答