Eri*_*sch 85 model-view-controller asp.net-mvc design-patterns business-logic-layer
首先,在任何人尖叫之前,我很难总结一个简单的标题.另一个标题可能是"域模型和MVC模型之间有什么区别?" 或"什么是模特?"
从概念上讲,我理解一个Model是视图和控制器使用的数据.除此之外,关于构成模型的内容似乎存在很多不同的意见.什么是域模型,应用模型,视图模型,服务模型等.
例如,在我最近提出的关于存储库模式的问题中,我被告知空白存储库是模型的一部分.但是,我已经阅读了其他意见,即模型应该从持久性模型和业务逻辑层中分离出来.毕竟,是不是存储库模式应该将具体的持久性方法与模型分离?其他人说Domain模型和MVC模型之间存在差异.
我们举一个简单的例子.MVC默认项目中包含的AccountController.我已经阅读了一些意见,其中包含的帐户代码设计不佳,违反了SRP等等.如果要为MVC应用程序设计一个"适当的"成员模型,那会是什么?
您将如何从模型中分离ASP.NET服务(成员资格提供程序,角色提供程序等)?或者你会吗?
我看待它的方式,模型应该是"纯粹的",也许是验证逻辑..但应该与业务规则分开(除了验证).例如,假设您有一条业务规则,说明在创建新帐户时必须通过电子邮件发送某人.在我看来,这并不属于模型.那它属于哪里?
有人关心这个问题吗?
Jos*_*osh 69
我这样做的方式 - 我并不是说它是对还是错,就是拥有我的视图,然后是适用于我视图的模型.此模型仅包含与我的视图相关的内容 - 包括数据注释和验证规则.控制器仅包含用于构建模型的逻辑.我有一个服务层,包含所有业务逻辑.我的控制器调用我的服务层.除此之外是我的存储库层.
我的域对象是单独存放的(实际上是在他们自己的项目中).他们有自己的数据注释和验证规则.在将数据库保存到数据库之前,我的存储库会验证域中的对象.因为我的域中的每个对象都继承自内置验证的基类,所以我的存储库是通用的并且验证所有内容(并且要求它继承自基类).
您可能认为拥有两组模型是代码重复,并且在一定程度上.但是,有完全合理的实例,域对象不适合视图.
例如,当使用信用卡时 - 我在处理付款时需要cvv,但我不能存储cvv(罚款5万美元).但是,我还希望您能够编辑您的信用卡 - 更改地址,姓名或到期日期.但是在编辑它时你不会给我这个号码或cvv,我当然不会在页面上以明文形式提供你的信用卡号码.我的域名具有保存新信用卡所需的这些值,因为您将它们提供给我,但我的编辑模型甚至不包括卡号或cvv.
这么多层的另一个好处是,如果架构正确,您可以使用结构图或其他IoC容器并交换件而不会对您的应用程序产生不利影响.
在我看来,控制器代码应该只是针对视图的代码.显示此信息,隐藏该信息等.服务层应包含您应用的业务逻辑.我喜欢在一个地方拥有所有这些,因此很容易改变或调整业务规则.存储库层应该相对愚蠢 - 缺乏业务逻辑,只查询数据并返回域对象.通过将视图模型与域模型分离,您在自定义验证规则方面具有更大的灵活性.这也意味着您不必将所有数据转储到隐藏字段中的视图中,并在客户端和服务器之间来回推送(或在后端重建它).然后,您的视图模型将仅包含与视图相关的信息 - 并且可以自定义视图逻辑或计数或枚举的bool,以便视图本身不会像复杂的逻辑语句那样混乱
<% if (!String.IsNullOrEmpty(Model.SomeObject.SomeProperty) &&
Model.SomeObject.SomeInt == 3 && ...) { %>
Run Code Online (Sandbox Code Playgroud)
虽然一切看起来都是分散的,但它的目的是以这种方式构建.它完美吗?并不是的.但我确实更喜欢它过去从控制器调用存储库并在控制器,存储库和模型中混合业务逻辑的一些设计.
Boz*_*zho 17
我经常想知道MVC元素究竟如何适合传统的Web应用程序结构,您可以在其中拥有视图(页面),控制器,服务和数据对象(模型).正如你所说,有很多版本.
我认为由于上述广泛接受的架构存在混淆,该架构使用"贫血域模型"(所谓的)抗性模式.我不会详细介绍贫血数据模型的"反模式"(你可以看一下我在这里解释一些事情的努力(基于Java,但与任何语言相关)).但简而言之,这意味着我们的模型只包含数据,而业务逻辑则放在服务/管理器中.
但是我们假设我们有域驱动的架构,我们的域对象就是他们期望的方式 - 拥有状态和业务逻辑.在这个以域为导向的视角中,事情就会出现:
我想这可以回答你的主要问题.当我们添加更多层时,例如存储库层,事情会变得复杂.通常建议它应该由放在模型中的业务逻辑调用(因此每个域对象都有一个对存储库的引用).在我链接的文章中,我认为这不是一个最好的做法.事实上,拥有服务层并不是一件坏事.顺便说一下,域驱动设计并不排除服务层,但它应该是"瘦"的,并且只协调域对象(因此没有业务逻辑).
对于广泛采用的贫血数据模型范例(好的或坏的),模型既是服务层又是数据对象.
| 归档时间: |
|
| 查看次数: |
26234 次 |
| 最近记录: |