3

在上周的工作中,我们举行了一次会议/演讲,讨论了重新思考我们如何做 MVC,基于我们老板可能进行的大量研究以及对其他 SO 问题的一些阅读。对我来说,一个收获是,当人们说“将逻辑与数据分离”时,我可能更准确地说“将逻辑与数据分离”。如果你做第一个,你可能会成为贫血域模型的牺牲品。我在这方面是正确的吗?

其次,我们了解到 MVC 不会在任何地方包含您的业务逻辑。这应该位于 Web 应用程序之外的单独服务层或 BLL 中。协调这两点似乎有点棘手 - 是否按照基本 OOP 原则的要求,特定逻辑与数据对象一起使用,还是在单独的层中?

这是我现在需要帮助的一个具体示例。我非常确信这将属于服务层,但我还有其他问题。假设我有一些行为将多个不同类型的不同实体作为输入。它运行,然后作为输出,它可以修改输入实体,并生成新实体作为记录。在我的情况下,它是为了游戏,但你可以说它就像一个交易。涉及多人,一些产品,并生成了收据。

  1. 一个简单的问题,你会把这个逻辑放在哪里?它是一个被实例化的单独的类吗?
  2. 难题(对我而言)是谁负责调用此代码?让控制器这样做会感觉不对。或者这正是它的工作?如果它不在任何一个特定页面上运行,而是在用户在特定时间后访问该站点时运行怎么办?基础控制器?
  3. 一般来说,您如何在“这属于我的实体类,因此它不仅仅是一堆 getter 和 setter”和“这属于我的服务层”之间做出决定?还是我把事情搞混了……实体类是否属于服务层?
4

1 回答 1

4

让我们先整理一些术语。正如您所说,您所说的“服务层”通常称为“域模型”,不要与 MVC 模型混淆。在最基本的层面上,MVC 模型封装了领域模型。两者如何交互不是由模式本身定义的,而是模型存储状态的逻辑方式是实现两种不同的状态:

  • 域状态——在现实世界中,这通常会以某种方式存储在数据库中,但域模型不应该将任何数据源暴露给 MVC 模型。这允许域模型保留适当的封装。任何改变或访问此数据的逻辑都应在此处使用相关但抽象的访问器来完成,以便 MVC 模型访问。

  • 应用程序状态——例如“当前正在编辑哪个记录?”

要回答您的问题,这实际上取决于您对数据的处理方式。如果您正在进行任何类型的处理,那么这应该在域模型中完成。如果您只是获取显示所需的数据集合,则 MVC 模型应查询域模型以检索相关数据。然后视图应该向模型查询此数据。

所以回答你的问题:

  1. 在这种特定情况下:处理数据的事务应该在域模型内。它可以直接访问所有相关数据,只需使用任何必需的参数进行调用。这促进了可重用性,因为它不直接绑定到 MVC 模型。
  2. 从技术上讲,如果您的控制器直接访问域模型,则它更接近于 MVVM 实现而不是 MVC 实现。但是,这并不是一件坏事,只要您的域模型采用与域逻辑无关的参数,就没有真正的问题。然而,控制器不应该构建域对象(例如创建用户帐户并将其传递给模型)。拥有位于 MVC 三元组之外的域模型的原因正是为了:因此,调用代码的内容无关紧要,域逻辑与其运行的体系结构无关。这是一件好事。MVC 是表现性的,有时域逻辑只是数据处理。关于“每当用户在特定时间后访问站点”这是域逻辑,因此当然应该进入域模型。
  3. 的确。实体(我假设您的意思是指单个域对象、用户、产品、博客等的对象?)本身可能不包含太多逻辑,因为它们主要是数据结构。一个订单可能有一个“getProducts()”或“getDeliveryAddress()”来获取相关实体,但域模型会对数据本身进行任何处理。

根据经验,几乎所有改变数据或处理来自多个实体的数据的逻辑都应该发生在域模型中。这有两个主要原因: 1. 可重用性,该逻辑可以在任何地方重用。2.封装。一旦开始将此逻辑放入实体中,您最终会遇到域实体依赖于其他域实体的情况。这会导致现实世界中的代码非常脆弱,因为您最终会在以后引入任意规则,例如“这些客户不必输入付款详细信息”。“这是一个公司客户,他们没有帐单地址”,如果您已经为您的“订单”建模

于 2012-12-10T23:48:01.940 回答