我一直在阅读许多提倡胖模型和瘦控制器方法的博客,尤其是。 Rails阵营。因此,路由器基本上只是找出在什么控制器上调用什么方法,并且所有控制器方法都在调用模型上的相应方法然后调出视图。所以我在这里有两个我不明白的问题:
你在哪里划线?这不仅仅是落入上帝的模式吗?
答案 0 :(得分:129)
将Rails视为MVC设计模式的主要内容可能不是最佳选择。所述框架具有一些固有的缺点(我在different post中对其进行了详细阐述)并且刚才社区已经开始解决这个问题。您可以将DataMapper2 development视为第一个主要步骤。
提供这种建议的人似乎受到了一个非常普遍的误解的折磨。所以让我先来清理一下:模型,在现代MVC设计模式中,不是类或对象。模型是一个层。
MVC模式背后的核心思想是Separation of Concerns,其中的第一步是表示层和模型层之间的划分。就像表示层分解为控制器(实例,负责处理用户输入),视图(实例,负责UI逻辑)和模板/布局一样,模型层也是如此。
模型层的主要部分是:
也称为域实体,业务对象或模型对象(我不喜欢后一个名称,因为它只会增加混淆)。这些结构是人们通常错误地称之为“模型”的结构。他们负责包含业务规则(针对特定域逻辑单元的所有数学和验证)。
存储抽象:
通常使用data mapper模式实现(不要与滥用此名称的ORMs混淆)。这些实例通常负责从域对象中存储信息并将其检索到域对象中。每个域对象都可以有多个映射器,就像有几种存储形式(DB,缓存,会话,cookie,/ dev / null)。
服务:
负责应用程序逻辑的结构(即域对象之间的交互以及域对象和存储抽象之间的交互)。它们应该像表示层与模型层交互的“接口”。这通常是Rails类代码最终出现在控制器中的。
这些群组之间的空格中还可能存在多种结构:DAOs,units of work和repositories。
哦......当我们谈论(在网络环境中)关于与MVC应用程序交互的用户时,它不是一个人。 “用户”实际上是您的网络浏览器。
控制器应该与服务进行交互,而不是使用一些可怕的单片模型。您将数据从用户输入传递到特定服务(例如MailService
或RecognitionService
)。这样控制器就会改变模型层的状态,但是它是通过使用一个清晰的API完成的,而不会弄乱内部结构(这会导致抽象漏洞)。
此类更改可能会导致一些立即反应,或者只影响视图实例从模型层请求的数据,或者两者都有。
每个服务都可以与域对象和存储抽象的任何数字(尽管通常只有少数)进行交互。例如,RecogitionService
对文章的存储抽象不太关心。
通过这种方式,您可以获得可在任何级别进行单元测试的应用程序,具有低耦合(如果正确实现)并且具有清晰易懂的架构。
但是,请记住:MVC不适用于小型应用程序。如果您正在使用MVC模式编写留言板页面,那么您做错了。此模式用于在大规模应用程序中强制执行法律和订单。
对于使用PHP作为主要语言的人来说,this post可能是相关的。这是一个模型层的描述,有一些代码片段。
答案 1 :(得分:5)
如果“模型”类的实施效果不佳,那么您的关注点是相关的。 模型类不应该做电子邮件(基础结构任务)。
真正的问题是MVC中的模型意味着什么。 它不仅限于几种方法的POCO类。 MVC中的模型意味着数据和业务逻辑。将其视为经典核心POCO模型的超集。
查看====控制器====模型--->业务流程层 - >核心模型
抛出基础架构程序集和数据访问层,并使用注入将其交付给BPL,然后您的进程正在按预期使用MVC。
BPL可以通过注入对象或界面模式来调用UoW / Respository模式,执行业务规则并调用基础结构功能。
因此,保持控制器瘦的建议并不意味着经典Core模型中的“person”类应该有50种方法,并直接调用Email。你认为这是错的是对的。
如果直接调用,可能仍需要Controller实例化基础结构类并将其注入BPL或核心层。应该有一个业务层或至少是经典对象模型类中编排调用的类。 好吧那就是我的“观点”无论如何; - )
对于MVC的通用概念wiki描述http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
一个谈论MVC中“M”的小博客。 http://www.thedeveloperday.com/skinny-controllers/
答案 2 :(得分:-1)
我认为你可以区分单个胖模型(可能名为App或Application),以及分解为逻辑组(业务,客户,订单,消息)的几个胖模型。后者是我构建应用程序的方式,每个模型大致对应于关系数据库中的数据库表或文档数据库中的集合。这些模型处理创建,更新和操作组成模型的数据的所有方面,无论是与数据库通信还是调用API。控制器非常薄弱,负责调用适当的模型并选择模板。