MVC中的业务逻辑

时间:2010-12-11 08:32:37

标签: design-patterns model-view-controller business-logic business-rules

我有两个问题:

Q1。 MVC模式中“业务逻辑”到底在哪里?我在模型和控制器之间感到困惑。

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

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

10 个答案:

答案 0 :(得分:167)

所有的拳头:
我相信你混合了MVC模式和基于n层的设计原则。

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

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

请看一下:Wikipedia article about multitier architecture

它说:

  

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

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

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

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

此技术与您使用域驱动设计还是基于事务脚本的方法无关
让我为你想象一下:


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


业务层:域逻辑 - 应用程序逻辑


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


您在上面看到的模型意味着您有一个使用MVC,DDD和数据库独立数据层的应用程序。
这是设计更大的企业Web应用程序的常用方法
但您也可以缩小它以使用简单的非DDD业务层(没有域逻辑的业务层)和直接写入特定数据库的简单数据层。 您甚至可以删除整个数据层并直接从业务层访问数据库,但我不建议这样做。

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

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

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

答案 - >它没有!
好吧 - 它有点但不完全。
这是因为MVC是一种在1970年代后期为Smalltalk-80编程语言开发的方法。当时GUI和个人计算机非常罕见,甚至没有发明万维网! 今天的大多数编程语言和IDE都是在20世纪90年代开发的。 那时计算机和用户界面与20世纪70年代完全不同 当你谈到MVC时,你应该记住这一点 Martin Fowler has written a very good article about MVC, MVP and today's GUIs.

答案 1 :(得分:157)

业务规则包含在模型中。

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

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

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

答案 2 :(得分:68)

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

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

在我看来,这种分离更加清晰。并且认识到存在不同类型的业务规则也意识到它们并非都必须在同一个地方。

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

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

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

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

答案 3 :(得分:25)

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

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

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

另见Wikipedia entry for Business Logic。有人提到Business LogicBusiness RulesWorkflow组成。

答案 4 :(得分:15)

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

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

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

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

答案 5 :(得分:7)

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

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

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

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

我想指出,在一个MVC组件中找到混合业务逻辑和数据访问的代码并不罕见,特别是如果应用程序没有使用多个层构建。但是,在大多数企业应用程序中,您通常会在表示层中找到具有MVC架构的多层体系结构。

答案 6 :(得分:4)

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

假设您的老板决定将表示层更改为其他内容,您会被搞砸!业务层应该是一个单独的程序集。模型包含来自业务层的数据,该数据传递到要显示的视图。然后在帖子上,例如,模型绑定到驻留在业务层中的Person类,并调用PersonBusiness.SavePerson(p);其中p是Person类。这就是我的工作(BusinessError类缺少,但也会在BusinessLayer中):enter image description here

答案 7 :(得分:1)

Q1:

业务逻辑可分为两类:

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

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

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

    有关模型和控制器之间的具体区别,请参阅此answer,对于非常精确的定义,请参阅此link,对于一个不错的Android示例,请参阅此link

    关键是上面“泥浆”和“弗兰克”所提到的注释都可以和“Pete”一样(业务逻辑可以根据业务逻辑的类型放入模型或控制器中) )。

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

    Q2:

    业务逻辑更通用,(如上所述,“decyclone”)我们之间有以下关系:

      

    业务规则⊂业务逻辑

答案 8 :(得分:0)

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

答案 9 :(得分:-5)

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

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

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

关于业务规则应该去哪里,没有严格的规则。在一些设计中,它们进入模型,而在其他设计中,它们包含在控制器中。但我认为最好将它们与控制器保持一致。让模型只关心数据库连接。