46

我们公司正在进行一些哲学辩论,关于调用业务逻辑应该在哪里执行 CRUD 操作。

我相信模型应该包含您的数据结构,并且控制器应该负责填充数据。

我的同事认为所有填充都应该在模型类本身中完成,并由控制器简单地调用。这使控制器保持整洁(但在我看来,会使模型混乱)。

他还认为,任何返回 Json 对象的调用都应该发生在模型中,而不是控制器中。该模型将向控制器返回一个数组,然后控制器将其作为 Json 对象返回。

每个有哪些不同的优点/缺点,是否有正确或错误的方法来做到这一点?

4

5 回答 5

76

所有业务逻辑都应该在MODEL中。

请记住,每一层的职责是:

  • 控制器 - 模型和视图之间的桥梁。决定下一步去哪里
  • 查看 - 显示数据,收集用户输入
  • 模型 - 业务逻辑,数据存储接口。

最大的收获之一是维护和(后来的)扩展。一般来说:

  • 如果您需要更改业务逻辑,则不需要修改控制器或视图。
  • 如果您更改视觉显示,则不需要修改模型或控制器。
  • 如果您更改工作流程,则不需要修改视图或模型。

为此,每一层都应该不知道其他层才能正常工作。例如,视图应该接收它的数据,并且不需要知道它来自哪里以正确显示它。控制器不需要了解模型的底层结构就可以与之交互。模型不应该知道如何显示数据(例如,格式化)或工作流。

“他还认为,任何返回 Json 对象的调用都应该发生在模型中,而不是控制器中。模型会向控制器返回一个数组,然后控制器会将其作为 Json 对象返回。”

不。模型不应该格式化数据。它也不应该读取格式化的数据。那就是污染模型,进入地狱所在的层次business logic = display logic

JSON(进来或出去)只是另一种观点。于是出门:

Data Store -> Model -> Controller -> View

进来:

View -> Controller -> Model -> Data Store
于 2012-10-02T16:10:46.217 回答
13

仅供参考,我的主要语言是 PHP,所以你可以对这一切持保留态度。

MVC 和受 MVC 启发的模式中的业务业务逻辑必须在模型层中。是的,模型应该是一个层,而不是一个类或对象。

大多数所说的逻辑将驻留在域对象中,但其中一些最终会出现在服务中,服务应该类似于模型层中的“顶级”结构,表示层(视图和控制器)通过它与模型层交互。

服务还应该促进存储抽象(数据映射器数据访问对象工作单元和/或存储库)与域对象之间的交互。这些结构将处理持久和临时存储并处理数据完整性。

这种分离简化了代码库的维护和测试。您无需接触数据库(或任何其他形式的存储)即可轻松测试域逻辑。

控制器(以及来自其他 MVVM 和 MVP 模式的等效结构)应该从用户请求中提取信息并更改模型层(通过使用服务)和视图的状态。

如果您实现 MVP 或 MVVM,那么类似控制器的组件将有额外的职责,包括从模型层到视图的数据传输,但在经典和 Model2 MVC 模式中,视图应该是一个活动结构,它从模型请求数据层。

至于 JSON 的生成,这实际上应该发生在视图中。视图应该包含所有(或大部分,取决于您使用模板的方式)表示逻辑。它应该从模型层(直接或通过中介)获取信息,并基于该信息生成响应(有时从多个模板创建它)。JSON 只是一种不同的响应格式。


2005 年发布的 Rails 框架产生了巨大的影响(而且大部分是负面的)。它的最初目的是成为原型设计的框架——快速创建一次性代码。为了实现这一点,他们将模式简化到了关注点分离被破坏的程度。

他们用活动记录结构的集合替换了模型层,这很容易在控制器中生成和合并视图功能,留下模板作为完整视图的替代品。它是最初目标的完美解决方案,但是当它开始在其他领域传播时,引入了大量对 MVC 和 MVC 启发的设计模式的误解,例如“视图只是一个模板”“模型是 ORM”

于 2012-10-02T17:13:03.190 回答
9

你的控制器方法应该尽可能的精简,这意味着数据访问属于模型(或者更具体地说,一个 Repository 对象)。

将您的控制器方法视为一个开关场......它们只负责将任务委派给其他方法执行。

如果您在控制器中编写任何 Linq 代码,则您正在创建一个依赖项,如果您的站点结构发生更改,则必须修改该依赖项,并且您可能会复制数据访问代码。但是GetCustomer在模型中仍然是GetCustomer,无论您从控制器中的何处调用它。那有意义吗?

比简单地访问数据更广泛的业务逻辑可以放入它自己的业务逻辑层,这被认为是模型的一部分。

我不太确定JSON。JSON 只是一种替代数据表示;如果您有一个实用方法可以将您的数据类转换为 JSON,请GetCustomer从模型中调用,并在您的控制器方法中执行到 JSON 的转换。

于 2012-10-02T16:13:44.857 回答
7

模型应该处理数据访问。

来自MSDN

楷模。模型对象是应用程序中实现应用程序数据域逻辑的部分。通常,模型对象检索模型状态并将其存储在数据库中。例如,Product 对象可能会从数据库中检索信息,对其进行操作,然后将更新的信息写回 SQL Server 数据库中的 Products 表。

于 2012-10-02T16:09:51.727 回答
2

在 MVC 中,模型负责处理数据访问。优点是所有数据访问代码都由模型逻辑封装。如果您在控制器中包含数据访问代码,您将膨胀控制器并破坏 MVC 模式。

于 2012-10-02T16:11:43.173 回答