胖模型、瘦控制器和 MVC 设计模式

Posted

技术标签:

【中文标题】胖模型、瘦控制器和 MVC 设计模式【英文标题】:Fat models, skinny controllers and the MVC design pattern 【发布时间】:2010-10-02 19:11:24 【问题描述】:

我刚刚阅读了blog post,它用银行类比来解释 MVC。我有几个月的使用 MVC 框架 (Cakephp) 开发 Web 应用程序的经验,所以我掌握了基础知识,但我开始看到一个主题,让我认为我在放置逻辑的地方采用了一种有缺陷的方法:

胖模型,瘦控制器 在模型中保留尽可能多的业务逻辑

在我的应用中,模型患有厌食症,而控制器则肥胖。我在控制器中拥有所有业务逻辑,除了模型中的关联和验证规则之外什么都没有。

通过我的控制器进行扫描,我现在可以识别出很多应该包含在模型中的逻辑:

该应用程序有列表,其中包含项目,并且可以对项目进行排名。将列表按排名顺序排列的排序逻辑位于控制器中。 同样,物品(物品模型)也有图像(图像模型)。每个项目可能有一个默认图像(由项目表中的 image_id 指定)。当一个项目与它的图像一起显示时,默认图像应该首先出现。我有在控制器中执行此操作的逻辑。 显示列表时,边栏中会显示相关列表。确定哪些列表相关的逻辑位于控制器中。

现在回答我的问题:

    通过上面给出的示例,我认为这些是当前属于模型的控制器中的逻辑实例,我是否走在正确的轨道上? 还有哪些其他逻辑领域(Web 应用程序共有)应该纳入模型? 我确信发现这个问题并改变我的设计模式是成功的一半,但即使我决定采用上面给出的示例并尝试将逻辑转移到模型中,我也不知道从哪里开始.任何人都可以通过在此处发布一些代码或链接到一些好的学习资源来为我指明正确的方向吗? CakePHP 的特定帮助会很棒,但我确信任何 MVC 都足够了。

【问题讨论】:

之前都听说过 :) 【参考方案1】:

给你“正确”的答案有点困难,因为其中一些涉及框架的细节(不管你正在使用的那些)。

至少在 CakePHP 方面:

    任何处理数据或数据操作的东西都应该在模型中。就 CakePHP 而言,一个简单的 find() 方法怎么样? ...如果它有可能会做一些“特殊”的事情(即回忆一组特定的“条件”),而你可能在其他地方需要它,这是一个很好的借口来包装模型的方法。

    不幸的是,从来没有一个简单的答案,重构代码是一个自然的过程。有时你只是醒了过来:“神圣的通心粉......应该在模型中!” (好吧,也许你不这样做,但我有:))

【讨论】:

博客作者撰写获奖答案 FTW!【参考方案2】:

我至少使用这两个“测试”来检查我的逻辑是否在正确的位置:

1) 如果我编写一个单元测试,很容易只创建一个“真实”对象来进行测试(= 您在生产中使用的对象)并且不包括很多其他对象,除了一些价值对象。需要一个实际的模型对象和一个实际的控制器对象来进行测试可能是您需要移动功能的信号。

2) 问自己一个问题:如果我添加了另一种使用这些类的方法,我是否需要以几乎复制粘贴的方式复制功能? ...这也可能是移动该功能的一个很好的理由。

也很有趣:http://www.martinfowler.com/bliki/AnemicDomainModel.html

【讨论】:

以上是关于胖模型、瘦控制器和 MVC 设计模式的主要内容,如果未能解决你的问题,请参考以下文章

django:胖模型和瘦控制器?

胖模型和瘦控制器听起来像是在创造上帝模型

iOS架构补完计划--浅谈架构模式(MVC/MVVM)

sundray AP切换胖/瘦模式升级和配置

MVC 架构中的数据和表单验证

OSI模型