199

我有两个问题:

Q1。“业务逻辑”到底在 MVC 模式中的什么位置?我对模型和控制器感到困惑。

Q2。“业务逻辑”和“业务规则”一样吗?如果不是,有什么区别?

如果你能用一个小例子来解释,那就太好了。

4

10 回答 10

212

首先:
我相信您将 MVC 模式和基于 n 层的设计原则混为一谈。

使用 MVC 方法并不意味着您不应该对应用程序进行分层。
如果您看到 MVC 更像是表示层的扩展,这可能会有所帮助。

如果您将非展示代码放入 MVC 模式中,您可能很快就会陷入复杂的设计。
因此,我建议您将业务逻辑放入单独的业务层中。

看看这个:关于多层架构的维基百科文章

它说:

今天,MVC 和类似的模型-视图-展示器 (MVP) 是关注点分离设计模式,专门应用于更大系统的表示层

无论如何......在谈论企业 Web 应用程序时,从 UI 到业务逻辑层的调用应该放在(表示)控制器内。

这是因为控制器实际上处理对特定资源的调用,通过调用业务逻辑来查询数据并将数据(模型)链接到适当的视图。

Mud 告诉你,业务规则进入了模型。
这也是正确的,但他混淆了(表示)模型(MVC 中的“M”)和基于层的应用程序设计的数据层模型。
因此,将与数据库相关的业务规则放在应用程序的模型(数据层)中是有效的。
但是您不应该将它们放在您的 MVC 结构表示层的模型中,因为这仅适用于特定的 UI。

该技术与您使用的是域驱动设计还是基于事务脚本的方法无关。

让我为你想象一下:


表示层:模型 - 视图 - 控制器


业务层:领域逻辑 - 应用逻辑


数据层:数据存储库 - 数据访问层


您在上面看到的模型意味着您有一个使用 MVC、DDD 和独立于数据库的数据层的应用程序。
这是设计大型企业 Web 应用程序的常用方法。

但是您也可以将其缩小以使用简单的非 DDD 业务层(没有领域逻辑的业务层)和直接写入特定数据库的简单数据层。
您甚至可以删除整个数据层并直接从业务层访问数据库,尽管我不推荐这样做。

这就是诀窍......我希望这会有所帮助......

[注意:] 您还应该意识到,如今应用程序中不止一个“模型”。通常,应用程序的每一层都有自己的模型。表示层的模型是特定于视图的,但通常独立于使用的控件。业务层也可以有一个模型,称为“领域模型”。当您决定采用域驱动方法时,通常会出现这种情况。这个“领域模型”包含数据以及业务逻辑(程序的主要逻辑),通常独立于表示层。表示层通常在某个“事件”(按下按钮等)上调用业务层以从数据层读取数据或将数据写入数据层。数据层也可能有自己的模型,通常与数据库相关。

问题是:这如何适应 MVC 概念?

答案-> 没有!
嗯 - 它有点,但不完全。
这是因为 MVC 是在 1970 年代后期为 Smalltalk-80 编程语言开发的一种方法。那时,图形用户界面和个人计算机还很不常见,甚至还没有发明万维网!当今的大多数编程语言和 IDE 都是在 1990 年代开发的。当时的计算机和用户界面与 1970 年代完全不同。
当您谈论 MVC 时,您应该牢记这一点。
Martin Fowler 写了一篇关于 MVC、MVP 和当今 GUI 的非常好的文章。

于 2013-06-12T12:27:03.037 回答
184

业务规则进入模型。

假设您正在显示邮件列表的电子邮件。用户单击其中一封电子邮件旁边的“删除”按钮,控制器通知模型删除条目 N,然后通知视图模型已更改。

也许管理员的电子邮件永远不应该从列表中删除。这是一个商业规则,知识属于模型。视图最终可能会以某种方式表示该规则——也许模型公开了一个“IsDeletable”属性,它是业务规则的函数,因此视图中的删除按钮对于某些条目是禁用的——但不包含规则本身在视图中。

该模型最终是您数据的看门人。您应该能够在完全不接触 UI 的情况下测试您的业务逻辑。

于 2010-12-11T08:45:34.347 回答
78

在我看来,业务逻辑一词并不是一个精确的定义。Evans 在他的《领域驱动设计》一书中谈到了两种类型的业务逻辑:

  • 领域逻辑。
  • 应用逻辑。

在我看来,这种分离更加清晰。随着认识到存在不同类型的业务规则,也认识到它们不一定都在同一个地方。

域逻辑是对应于实际域的逻辑。因此,如果您正在创建一个会计应用程序,那么域规则将是关于帐户、过帐、税收等的规则。在敏捷软件规划工具中,这些规则将是诸如根据积压中的速度和故事点计算发布日期之类的东西,等等

对于这两种类型的应用程序,CSV 导入/导出可能是相关的,但 CSV 导入/导出规则与实际域无关。这种逻辑就是应用逻辑。

领域逻辑肯定会进入模型层。该模型还对应于 DDD 中的领域层。

然而,应用程序逻辑不一定必须放置在模型层中。这可以直接放在控制器中,或者您可以创建一个单独的应用程序层来托管这些规则。在这种情况下最合乎逻辑的将取决于实际应用。

于 2011-08-28T16:40:38.080 回答
32

A1:Business LogicModel参与其中MVC。的作用Model是包含数据和业务逻辑。Controller另一方面负责接收用户输入并决定做什么。

A2:ABusiness Rule是 的一部分Business Logic。他们有has a关系。Business LogicBusiness Rules

看看Wikipedia entry for MVC。转到概述,其中提到了MVC模式的流程。

还看Wikipedia entry for Business Logic。提到Business LogicBusiness Rules和组成Workflow

于 2010-12-11T08:46:04.533 回答
21

正如几个答案所指出的,我相信对多层与 MVC 架构存在一些误解。

多层架构涉及将您的应用程序分解为层/层(例如表示、业务逻辑、数据访问)

MVC 是应用程序表示层的一种架构风格。对于非平凡的应用程序,不应将业务逻辑/业务规则/数据访问直接放入模型、视图或控制器中。这样做会将业务逻辑放在表示层中,从而减少代码的重用和可维护性。

模型是放置业务逻辑的一个非常合理的选择,但更好/更易于维护的方法是将表示层与业务逻辑层分开,并创建一个业务逻辑层,并在需要时简单地从模型中调用业务逻辑层。业务逻辑层将依次调用数据访问层。

我想指出,在 MVC 组件之一中找到混合业务逻辑和数据访问的代码并不少见,尤其是在应用程序不是使用多层架构的情况下。但是,在大多数企业应用程序中,您通常会在表示层中找到具有 MVC 架构的多层架构。

于 2017-08-25T13:13:02.393 回答
15

这是一个已回答的问题,但我会给我的“一分钱”:

业务规则属于模型。“模型”总是由(逻辑或物理分离的)组成:

  • 表示模型- 一组非常适合在视图中使用的类(它针对特定的 UI/表示而定制),
  • 域模型- 模型的 UI 独立部分,以及
  • 存储库- “模型”的存储感知部分。

业务规则存在于域模型中,以适合表示的形式暴露给“表示”模型,并且有时在“数据层”中复制(或强制执行)。

于 2013-07-15T03:45:00.323 回答
7

将业务层放在 MVC 项目的模型中是没有意义的。

假设您的老板决定将表示层更改为其他内容,您会被搞砸的!业务层应该是一个单独的程序集。模型包含来自业务层的数据,这些数据传递给视图以显示。然后在 post 例如,模型绑定到驻留在业务层中的 Person 类并调用 PersonBusiness.SavePerson(p); 其中 p 是 Person 类。这就是我所做的(缺少 BusinessError 类,但也会进入 BusinessLayer):在此处输入图像描述

于 2017-02-03T18:44:59.843 回答
2

Q1:

业务逻辑可以分为两类:

  1. 域逻辑,例如对电子邮件地址的控制(唯一性、约束等)、获取产品的发票价格,或者根据其产品对象计算购物车的总价。

  2. 更广泛和复杂的工作流程,称为业务流程,例如控制学生的注册流程(通常包括几个步骤,需要不同的检查,并且具有更复杂的约束条件)。

第一类属于模型第二属于控制器。这是因为第二类的案例是广泛的应用逻辑,将它们放在模型中可能会混合模型的抽象(例如,我们不清楚是否需要将这些决策放在一个模型类或另一个模型类中,因为它们是相关的二者皆是!)。

请参阅此答案以了解模型和控制器之间的具体区别,此链接以获得非常准确的定义,以及此链接以获得一个不错的 Android 示例。

关键是上面“Mud”和“Frank”提到的注释都可以是真的,也可以是“Pete”的(根据业务逻辑的类型,业务逻辑可以放在模型或控制器中)。

最后,请注意 MVC 因上下文而异。例如,在 Android 应用程序中,建议了一些与基于 Web 的定义不同的替代定义(例如,参见这篇文章)。


Q2:

业务逻辑更笼统,(如上面提到的“decyclone”)我们之间有以下关系:

业务规则⊂业务逻辑

于 2016-02-16T17:45:39.423 回答
2

为什么不引入一个服务层。那么你的控制器将更精简且更具可读性,那么你的所有控制器功能将是纯动作。您可以在服务层中根据需要分解业务逻辑。代码可重用性很高。对模型和存储库没有影响。

于 2019-09-20T06:12:58.400 回答
-5

模型 = CRUD 数据库操作的代码。

控制器 = 响应用户操作,并将用户对数据检索或删除/更新的请求传递给模型,具体取决于组织特定的业务规则。这些业务规则可以在辅助类中实现,或者如果它们不太复杂,直接在控制器操作中实现。控制器最终要求视图更新自己,以便以新显示的形式向用户提供反馈,或者像“更新,谢谢”等消息,

View = 基于对模型的查询生成的 UI。

关于业务规则的去向,没有硬性规定。在某些设计中,它们进入模型,而在其他设计中,它们包含在控制器中。但我认为最好将它们与控制器一起保存。让模型只关心数据库连接。

于 2013-03-14T15:22:51.130 回答