MVC中的业务逻辑

我有两个问题:

Q1。“业务逻辑”在MVC模式中的具体位置是什么?我分不清模型和控制器。

Q2。“业务逻辑”与“业务规则”相同吗?如果不是,有什么区别?

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

159835 次浏览

业务规则在模型中。

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

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

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

A1:业务逻辑转到MVC中的Model部分。Model的作用是包含数据和业务逻辑。另一方面,Controller负责接收用户输入并决定做什么。

A2: Business RuleBusiness Logic的一部分。它们有一个has a关系。Business LogicBusiness Rules

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

再看看Wikipedia entry for Business Logic。上面提到Business LogicBusiness RulesWorkflow组成。

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

  • 域逻辑。
  • 应用程序逻辑。

在我看来,这种分离要清楚得多。在认识到有不同类型的业务规则的同时,也认识到它们不一定都去同一个地方。

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

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

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

然而,应用程序逻辑并不一定要放在模型层中。这些规则可以直接放在控制器中,也可以创建一个单独的应用程序层来承载这些规则。在这种情况下,什么是最合乎逻辑的取决于实际的应用程序。

Model =用于CRUD数据库操作的代码。

Controller =响应用户操作,并根据特定于组织的业务规则将用户的数据检索或删除/更新请求传递给模型。这些业务规则可以在助手类中实现,如果不是太复杂的话,也可以直接在控制器操作中实现。控制器最后要求视图更新自己,以便以新显示的形式给用户反馈,或者像'updated, thanks'之类的消息,

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

关于业务规则应该放在哪里,没有硬性规定。在一些设计中,它们进入模型,而在另一些设计中,它们包含在控制器中。但我认为最好还是把它们放在控制器里。让模型只关心数据库连通性。

首先:
我相信你混淆了MVC模式和基于n层的设计原则 使用MVC方法并不意味着你不应该分层你的应用程序 如果你认为MVC更像是表示层的扩展,这可能会有所帮助 如果你把非表示代码放在MVC模式中,你可能很快就会在一个复杂的设计中结束 因此,我建议你把你的业务逻辑放在一个单独的业务层中 只要看看这个:维基百科上关于多层架构的文章

它说:< / p >

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

< p >无论如何……当讨论企业web应用时,从UI到业务逻辑层的调用应该放在(表示)控制器内 这是因为控制器实际处理对特定资源的调用,通过调用业务逻辑查询数据,并将数据(模型)链接到适当的视图。 < br > < br > Mud告诉你业务规则进入模型 这也是正确的,但是他混淆了(表示)模型(MVC中的“M”)和基于层的应用程序设计的数据层模型 因此,将数据库相关业务规则置于应用程序的模型(数据层)中是有效的 但是不应该将它们放在mvc结构表示层的模型中,因为这只适用于特定的UI。 < br > < br > 这种技术与你使用的是领域驱动的设计还是基于事务脚本的方法无关
让我想象一下:


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


业务层:领域逻辑——应用程序逻辑


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


你在上面看到的模型意味着你有一个使用MVC, DDD和数据库独立的数据层的应用程序 这是设计大型企业web应用程序的常用方法
但是您也可以将其缩减为使用简单的非ddd业务层(没有域逻辑的业务层)和直接写入特定数据库的简单数据层 您甚至可以放弃整个数据层,直接从业务层访问数据库,尽管我不建议这样做。 < br > < br > 这就是诀窍……

< p >[注:] 您还应该了解这样一个事实,即现在一个应用程序中不止有一个“模型”。 通常,应用程序的每一层都有自己的模型。 表示层的模型是特定于视图的,但通常独立于所使用的控件。 业务层也可以有一个模型,称为“领域模型”。当您决定采用领域驱动方法时,通常会出现这种情况。 这个“域模型”包含数据和业务逻辑(程序的主要逻辑),通常独立于表示层。 表示层通常在某个“事件”(按下按钮等)时调用业务层从数据层读取数据或向数据层写入数据。 数据层也可能有自己的模型,通常与数据库相关。它通常包含一组实体类以及数据访问对象(dao)

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

答案->它不!< br > 嗯,它有点像,但不完全是。这是因为MVC是在20世纪70年代后期为Smalltalk-80编程语言开发的一种方法。在那个时候,gui和个人电脑还很少见,万维网甚至还没有发明! 今天的大多数编程语言和ide都是在20世纪90年代开发的。 那时的计算机和用户界面与20世纪70年代的计算机和用户界面完全不同 当你谈论MVC时,你应该记住这一点 Martin Fowler写了一篇关于MVC、MVP和当今gui的很好的文章。 < / p >

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

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

  • 演示模型 -一组非常适合在视图中使用的类(它是针对特定的UI/表示定制的),
  • 域模型 -模型中与ui无关的部分
  • 存储库 -“模型”的存储感知部分。

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

Q1:

业务逻辑可以分为两类:

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

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

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

在这个回答中可以看到模型和控制器的具体区别,在这个链接中可以看到非常精确的定义,在这个链接中可以看到一个很好的Android示例。

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

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


Q2:

业务逻辑更一般,(正如上面提到的“反气旋”)它们之间的关系如下:

业务规则业务逻辑

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

假如你的老板决定把演示层换成别的东西,你就完蛋了!业务层应该是一个单独的程序集。Model包含来自业务层的数据,这些数据传递给视图进行显示。然后在post中,例如,模型绑定到驻留在业务层的Person类,并调用PersonBusiness.SavePerson(p);其中p是Person类。以下是我所做的(BusinessError类缺失,但也会在BusinessLayer中):enter image description here

正如几个答案所指出的,我相信人们对多层架构和MVC架构有一些误解。

多层架构包括将你的应用程序分解成几层(例如,表示、业务逻辑、数据访问)

MVC是应用程序表示层的一种体系结构样式。对于重要的应用程序,业务逻辑/业务规则/数据访问不应该直接放在模型、视图或控制器中。这样做会将业务逻辑放在表示层,从而降低代码的重用性和可维护性。

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

我想指出的是,在一个MVC组件中发现混合了业务逻辑和数据访问的代码并不少见,特别是在应用程序没有使用多层架构的情况下。然而,在大多数企业应用程序中,您通常会在表示层中发现带有MVC体系结构的多层体系结构。

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