MVC中的业务逻辑
我有两个问题:
Q1。 MVC模式中的“业务逻辑”究竟在哪里? 我对模型和控制器感到困惑。
Q2。 “业务逻辑”和“业务规则”是一样的吗? 如果不是,有什么区别?
如果你能用一个小例子来解释,那将是很棒的。
业务规则进入模型。
假设您正在显示邮件列表的电子邮件。 用户点击其中一个电子邮件旁边的“删除”button,控制器通知模型删除条目N,然后通知视图模型已经改变。
也许pipe理员的电子邮件不应该从列表中删除。 这是一个商业规则,知识属于模型。 视图最终可能以某种方式代表这个规则 – 也许模型公开了一个“IsDeletable”属性,这是一个业务规则的function,因此视图中的删除button被禁用某些条目 – 但规则本身不包含在视图中。
这个模型最终是你的数据守门员。 你应该能够testing你的业务逻辑,而不用接触UI。
所有拳头:
我相信你正在混合MVC模式和基于n层的devise原则。
使用MVC方法并不意味着你不应该分层你的应用程序。
如果您看到MVC更像是表示层的扩展,则可能会有所帮助。
如果将非表示代码放在MVC模式中,则很快就会出现复杂的devise。
因此,我build议您将业务逻辑放入单独的业务层。
只要看看这个: 关于多层架构的维基百科文章
它说:
今天,MVC和类似的模型 – 视图 – 演示者(MVP)是分离关注的devise模式,专门应用于更大系统的表示层 。
无论如何,当谈论企业Web应用程序时 ,从UI到业务逻辑层的调用应该被放置在(表示)控制器中。
这是因为控制器实际上处理对特定资源的调用,通过调用业务逻辑来查询数据,并将数据(模型)链接到适当的视图。
泥告诉你,商业规则进入模型。
这也是事实,但他混淆了(演示)模型(MVC中的“M”)和基于层的应用程序devise的数据层模型。
因此,将与数据库相关的业务规则放置在应用程序的模型(数据层)中是有效的。
但是你不应该把它们放在MVC结构的表示层的模型中,因为这只适用于特定的UI。
这种技术独立于您使用域驱动devise或基于事务脚本的方法。
让我为你想象:
表示层:模型 – 视图 – 控制器
业务层:域逻辑 – 应用程序逻辑
数据层:数据存储库 – 数据访问层
您在上面看到的模型意味着您有一个使用MVC,DDD和数据库独立数据层的应用程序。
这是devise更大型企业Web应用程序的常用方法。
但是,您也可以将其缩小为使用简单的非DDD业务层(无域逻辑的业务层)和直接写入特定数据库的简单数据层。
你甚至可以删除整个数据层,直接从业务层访问数据库,尽pipe我不推荐它。
这就是诀窍…我希望这有助于…
[注意:]你也应该意识到,现在应用程序中不止有一个“模型”。 通常,应用程序的每一层都有自己的模型。 表示层的模型是视图特定的,但通常独立于使用的控件。 业务层也可以有一个模型,称为“域模型”。 当您决定采取领域驱动的方法时,情况就是这样。 这个“域模型”包含数据和业务逻辑(程序的主要逻辑),通常独立于表示层。 表示层通常在特定的“事件”(按下button等)上调用业务层以从数据层读取数据或将数据写入数据层。 数据层也可能有它自己的模型,通常是与数据库相关的。 它通常包含一组实体类以及数据访问对象(DAO)。
问题是:这如何融入MVC概念?
答案 – >它不!
那么 – 这样做,但不完全。
这是因为MVC是在20世纪70年代后期为Smalltalk-80编程语言开发的一种方法。 当时的graphics用户界面和个人电脑很less见,万维网甚至没有发明! 当今的大多数编程语言和IDE都是在20世纪90年代开发的。 那时候的电脑和用户界面与七十年代的完全不一样。
当你谈论MVC时,你应该记住这一点。
Martin Fowler写了一篇关于MVC,MVP和当今GUI的非常好的文章。
在我看来,商业逻辑这个词不是一个确切的定义。 埃文斯在他的书“领域驱动devise”中谈到了两种业务逻辑:
- 域逻辑。
- 应用程序逻辑
这种分离在我看来更加清晰。 而且意识到有不同types的业务规则也意识到它们并不一定都是一致的。
域逻辑是对应于实际域的逻辑。 所以,如果你正在创build一个会计应用程序,那么域规则就是关于账户,贴子,税收等的规则。在一个敏捷软件规划工具中,这些规则就像计算发行date,基于积压中的速度和故事点,等等
对于这两种types的应用程序,CSV导入/导出可能是相关的,但CSV导入/导出的规则与实际的域无关。 这种逻辑就是应用逻辑。
领域逻辑肯定会进入模型层。 该模型也将对应于DDD中的领域层。
然而,应用程序逻辑不一定要放置在模型层中。 这可以直接放置在控制器中,也可以创build一个独立的应用程序层来托pipe这些规则。 在这种情况下最合乎逻辑的将取决于实际应用。
A1 :业务逻辑在MVC
进入Model
部分。 Model
作用是包含数据和业务逻辑。 另一方面, Controller
负责接收用户input并决定要做什么。
A2 : Business Rule
是Business Logic
一部分。 他们有has a
关系。 Business Logic
有Business Rules
。
看看Wikipedia entry for MVC
。 转到概述它提到了MVC
模式的stream程。
另请Wikipedia entry for Business Logic
。 提到Business Logic
是由Business Rules
和Workflow
。
这是一个回答的问题,但我会给我“一分钱”:
业务规则属于模型。 “模型”总是由(逻辑上或物理上分离的)组成:
- 演示模型 – 适合在视图中使用的一组类(它是针对特定的UI /演示而定制的),
- 领域模型 – 模型的与UI无关的部分,以及
- 存储库 – “模型”的存储感知部分。
业务规则存在于领域模型中,以适合演示文稿的forms展现给“演示”模型,并有时在“数据层”中被复制(或者被强制执行)。
正如有几个答案指出的,我认为对于多层与MVC架构存在一些误解。
多层体系结构涉及将应用程序分为多个层/层(例如,表示,业务逻辑,数据访问)
MVC是应用程序表示层的体系结构风格。 对于非平凡的应用程序,业务逻辑/业务规则/数据访问不应直接放置到模型,视图或控制器中。 为此,将业务逻辑放置在表示层中,从而减less代码的重用性和可维护性。
该模型是放置业务逻辑的非常合理的selectselect,但更好/更可维护的方法是将表示层与业务逻辑层分开,并创build业务逻辑层,并在需要时从模型中调用业务逻辑层。 业务逻辑层将依次调用到数据访问层。
我想指出的是,在其中一个MVC组件中查找混合业务逻辑和数据访问的代码并不罕见,特别是如果应用程序不是使用多层构build的。 但是,在大多数企业应用程序中,通常会在表示层中find具有MVC体系结构的多层体系结构。
Q1:
业务逻辑可以分为两类:
-
域名逻辑,如电子邮件地址(唯一性,约束条件等)的控件,获取发票产品的价格,或者根据产品对象计算shoppingCart的总价格。
-
更广泛和更复杂的工作stream程称为业务stream程,例如控制学生的注册stream程(通常包括几个步骤,需要不同的检查和更复杂的约束)。
第一类进入模型 , 第二类属于控制器 。 这是因为第二类的情况是广泛的应用逻辑,把它们放在模型中可能会混合模型的抽象(例如,我们是否需要将这些决策放在一个模型类或另一个模型类中是不明确的,因为它们是相关的二者皆是!)。
看到这个答案模型和控制器之间的具体区别,这个链接非常确切的定义,也是一个很好的Android例子这个链接 。
重点是上面提到的“泥”和“弗兰克”的注释可以是真实的,也可以是“Pete”(业务逻辑可以放在模型中,或者根据业务逻辑types放在控制器中)。
最后,请注意,MVC因环境而异。 例如,在Android应用程序中,build议了一些与基于Web的应用程序不同的定义(请参阅本文后面的例子)。
Q2:
业务逻辑更一般化(就像上面提到的“旋风”),我们之间有如下关系:
业务规则⊂业务逻辑
将业务层放入MVC项目的模型中没有任何意义。
说你的老板决定把表示层改成别的东西,你就会被搞砸了! 业务层应该是一个独立的程序集。 模型包含来自传递到视图以显示的业务层的数据。 然后在post上,例如,模型绑定到驻留在业务层的Person类,并调用PersonBusiness.SavePerson(p); 其中p是Person类。 这就是我所做的(BusinessError类缺失,但也会在BusinessLayer中):
模型= CRUD数据库操作的代码。
Controller =响应用户操作,并将用户的数据检索或删除/更新请求传递给模型,但要遵守特定于组织的业务规则。 这些业务规则可以在助手类中实现,或者如果它们不是太复杂,则直接在控制器操作中实现。 控制器最后要求视图更新自身以便以新的显示forms或“更新,感谢”等消息给用户提供反馈,
查看=根据模型上的查询生成的UI。
关于业务规则应该去哪里,没有硬性规定。 在一些devise中,他们进入模型,而在其他devise中,他们包含在控制器中。 但是我认为让他们跟控制者比较好。 让模型只关心数据库连接。