13

操作Model类成员的方法应该在Model还是在Controller中实现?这是否取决于这种操作有多“重”?

我所说的“操纵”是指:

  1. 得到一个班级成员

  2. 根据该类成员进行长时间计算

  3. 返回与此类相关的另一个值

例如,Board class其中包含一个单元矩阵成员。现在我想实现一个根据特定单元格位置返回所有周围单元格的方法。

模型或视图是否负责实现上述内容?

如果此问题属于另一个 Stack Exchange QA 站点,我将欢迎将我的帖子移至该站点的建议。

4

4 回答 4

16

保持你的控制器精简,不要让它们做太多事情,这符合 SOLID 中面向对象设计的单一责任原则。如果你有胖控制器,它们就会变得难以测试和维护。

至于模型,我以前有愚蠢的模型,只是映射到数据库表,这是受您在 Web 上看到的大多数示例应用程序的启发,但现在我不这样做了。

我(尝试)遵循领域驱动设计的原则,其中模型(DDD 术语中的实体)位于应用程序的中心,它们被期望封装与实体相关的行为,它们是智能模型(所以是的,逻辑在这种情况下,与对象相关的将与它一起存在)。DDD 是一个更大的话题,它与 MVC 没有直接关系,但它背后的原理可以帮助您更好地设计应用程序,如果您在 Google 上搜索 DDD,可以找到很多材料和示例应用程序。

此外,Ruby On Rails 社区——似乎激发了大多数 MVC 框架——似乎也对拥有 Fat Models 和 Skinny Controllers 进行了炒作。

最重要的是,您可以将视图模型添加到您的组合中,这对我很有帮助。在这种情况下,您可以使用 ViewModel 来表示模型的一个愚蠢子集,仅用于生成视图,它使您的生活更轻松,并进一步将您的视图与模型分开,这样它们就不会影响您的设计不必要的决定。

于 2012-11-25T10:53:54.677 回答
11

您所说的“模型”实际上是域对象。MVC 中的实际模型只是一个层,而不是具体的东西。

在您的特定示例中,Board应该有一个返回此列表的方法。我假设,您实际上正在获得它,因为您需要与这些细胞进行进一步的交互。

这就是模型层中的服务发挥作用的地方。如果使用它们,它们是模型层的外部部分,包含应用程序逻辑——不同域对象之间的交互以及持久性(通常是数据映射器工作单元)与域对象之间的交互。

假设您正在制作游戏,并且您和玩家执行并进行 AoE 攻击。控制器持有负责此功能的服务并发送命令:此玩家将 AoE 朝这个方向瞄准,执行它

服务实例化Board并询问目标位置的周围单元。然后它对它获取的集合中的每个单元格执行“损坏”。逻辑完成后,它告诉工作单元实例提交所有发生在Board.

控制器不关心服务做什么的细节。它不应该收到任何反馈。当执行到达视图时,它从模型层请求最新的更改并修改 UI。作为额外的好处 - 服务让您阻止业务逻辑在表示层中泄漏(主要由视图和控制器组成)。

域对象应该只包含处理其状态的方法。

于 2012-11-25T11:09:09.463 回答
6

我认为这与 MVC 关系不大,而与常规软件工程有很大关系。

我个人会毫不犹豫地在模型中进行琐碎的计算,但会非常警惕模型。

现在,MVC 代表模型视图控制器这一事实并不一定意味着一切都应该是视图、模型或控制器。如果您觉得有必要将职责转移到一个不真正符合 M、V 或 C 资格的单独类,我不明白您为什么不应该这样做。

你实现它的方式取决于你。您可以将此单独的类用作“顶级”(因为没有更好的术语)对象,或者将模型的方法委托给它,以隐藏您正在使用它的事实。我可能会选择后者。

不过,一切都值得商榷。每个人和他们的妹妹似乎对如何正确地做 MVC 有不同的看法。

我,我只是把它当作一个指导方针。当然,这是一个好主意,因为它可以让您更好地分离关注点,但最终——正如它总是发生的那样——没有一种万能的方法来应用它,你不应该受到它的过度约束,以至于一切都必须是视图、模型或控制器。

于 2012-11-25T10:55:08.050 回答
-2

根据最佳实践,我们应该使用仅具有获取访问权限的计算字段的属性。例如 public double TotalCost { get { return this.Role.Cost * TotalHour; } }

于 2014-07-07T11:45:53.220 回答