首先,在任何人尖叫杜佩之前,我很难用一个简单的标题来概括它。另一个标题可能是“域模型和MVC模型之间有什么区别?”或“什么是模型?”

从概念上讲,我理解一个模型是视图和控制器使用的数据。除此之外,关于构成模型的原因,似乎有很多不同的意见。什么是域模型,与应用程序模型相对于视图模型,与服务模型等。

例如,在我最近问的有关存储库模式的问题中,我被告知Blank,该存储库是模型的一部分。但是,我读过其他观点,即该模型应与持久模型和业务逻辑层分开。毕竟,存储库模式不是应该从模型中解除具体持久方法吗?其他人说,域模型和MVC模型之间存在差异。

让我们以一个简单的例子。 MVC默认项目包含的帐户控制器。我读过几种意见,即包含的帐户代码是设计不良,违反SRP等。

您如何将ASP.NET服务(会员提供者,角色提供商等)分开?还是你会吗?

我的看法,模型应该是“纯”的,也许具有验证逻辑..但应与业务规则(除了验证之外)分开。例如,假设您有一条业务规则,说在创建新帐户时必须通过电子邮件发送电子邮件。在我看来,这并不真正属于模型。那么它属于哪里?

有人在乎对这个问题有任何启示吗?

有帮助吗?

解决方案

我做的方式 - 我并不是说这是对还是错,就是要有我的观点,然后是适用于我的观点的模型。该模型仅具有与我的观点相关的内容 - 包括数据注释和验证规则。控制器仅容纳用于构建模型的逻辑。我有一个拥有所有业务逻辑的服务层。我的控制器称我的服务层。除此之外,我的存储库层。

我的域对象分别包含(实际上是在自己的项目中)。他们有自己的数据注释和验证规则。我的存储库在将它们保存到数据库中之前验证了我的域中的对象。因为我域中的每个对象都从内置验证的基类继承,所以我的存储库是通用的,并验证了所有内容(并且要求其从基类继承)。

您可能会认为,拥有两组模型是代码的重复,这在一定程度上。但是,在某些情况下,域对象不适合视图。

例如,在使用信用卡时 - 处理付款时必须需要CVV,但我无法存储CVV(这样做是50,000美元的罚款)。但是,我也希望您能够编辑您的信用卡 - 更改地址,姓名或到期日期。但是,您不会在编辑时给我数字或CVV,我当然不会将您的信用卡号码放在页面上的纯文本中。我的域具有保存新信用卡所需的这些值,因为您将其提供给我,但是我的编辑模型甚至不包括卡号或CVV。

这么多层的另一个好处是,如果正确架构,您可以使用structuremap或另一个IOC容器并交换零件,而不会对您的应用产生不利影响。

我认为,控制器代码仅应在视图中针对定位。显示此信息,藏起来等等。服务层应容纳您的应用程序的业务逻辑。我喜欢将所有这些都放在一个地方,因此很容易更改或调整业务规则。存储库层应相对愚蠢 - 没有业务逻辑,仅查询您的数据并返回域对象。通过将视图模型与域模型分开,您在自定义验证规则方面具有更大的灵活性。这也意味着您不必在隐藏的字段中将所有数据转移到视图中,而是在客户端和服务器之间来回推动(或在后端重建)。然后,您的视图模型将仅包含与视图相关的信息 - 可以自定义以具有视图逻辑或计数或枚举的布尔,以使视图本身不会像复杂的逻辑语句一样混乱

<% if (!String.IsNullOrEmpty(Model.SomeObject.SomeProperty) && 
    Model.SomeObject.SomeInt == 3 && ...) { %>

尽管一切似乎都散布并过高,但它的目的是以这种方式进行架构。这是完美的吗?并不真地。但是,我确实更喜欢从控制器调用存储库的某些过去设计,并在控制器,存储库和模型中混合业务逻辑。

其他提示

我经常想知道MVC元素如何完全适合传统的Web应用程序结构,其中您具有视图(页面),控制器,服务和数据对象(模型)。正如您所说,有很多版本。

我认为存在混乱是因为上述所述,广泛接受的建筑,它使用了“贫血领域模型”(所谓的)-ANTI模式。我不会详细介绍贫血数据模型的“反理解”(您可以研究我的努力来解释事物 这里 (基于Java,但与任何语言有关))。但简而言之,这意味着我们的模型仅包含数据,而业务逻辑则放在服务/经理中。

但是让我们假设我们有 域驱动的建筑, ,并且我们的域对象是它们的期望 - 具有州和业务逻辑。在这个域驱动的观点中,事物出现了:

  • 视图是UI
  • 控制器收集UI的输入,在模型上调用方法,并将响应发送给UI
  • 该模型是我们的业务组件 - 持有数据,但也具有业务逻辑。

我想这回答了您的主要问题。当我们添加更多层(例如存储库层)时,事情会变得复杂。通常建议将其通过模型中的业务逻辑调用(因此每个域对象都有对存储库的引用)。在我链接的我的文章中,我认为这不是最好的做法。实际上,拥有服务层并不是一件坏事。顺便说一句,域驱动的设计并不排除服务层,而是应该是“薄”的,并且仅协调域对象(因此那里没有业务逻辑)。

对于广泛采用的贫血数据模型范式(好是坏),该模型既是服务层和您的数据对象。

在我看来,

模型 -

不应包含业务逻辑,它应该是可插入的(例如WCF场景)。它用于绑定到视图,因此应具有属性。

商业逻辑 -

它应放在“域服务层”上,完全是单独的层。另外,将在此处添加一层“应用程序服务”。

App Services与域服务层进行对话以应用业务逻辑,然后最后返回模型。

因此,控制器将向模型询问应用程序服务,流程会像

    Controller->Application Services(using domain services)->Model

MVC模式和ASP.NET框架对模型的应有区别没有区别。

MS自己的示例包括模型中的持久性课程。您有关会员资格在模型中的问题。这取决于。您的模型中的课程是否由某物拥有?谁登录与显示哪些数据之间有链接?是否存在可编辑的权限系统的数据部分过滤?谁是上次更新或编辑您域中的对象部分,因为其他人需要看到它或其他用于后端支持的东西?

电子邮件示例也取决于。您特别熟悉域活动或eventing吗?您是否有单独的服务来发送电子邮件?发送电子邮件的一部分的行为是在系统范围之外的应用级别问题吗? UI是否需要知道是否成功发送了电子邮件?未能发送需求重新恢复的电子邮件会吗?发送电子邮件的内容是否需要存储以获得支持或客户服务要求?

这些类型的问题过于广泛和主观,但我正在回答,因此您和所有投票给您的人都可以理解这一点。

您的需求/时间表/资源都流血到系统的体系结构中。即便是 收入模型 可以产生效果。您还必须考虑要拍摄的模式。 DDD与持久性AS模型应用程序有很大不同,并且两者之间的所有斜率也适用于某些应用程序。您正在拍摄测试应用程序吗?所有这些都有效果。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top