了解MVC:模型上的“胖”概念是什么,控制器上的“瘦”?
我试图理解模型上的“胖”概念与控制器上的“瘦”,从我一直在讨论我有以下例子(这是从freenode讨论):
问:关于MVC范式,它说的胖模型,瘦的控制器。 我在这里想,如果我有很多方法(在控制器上),只使用几个抽象方法来CRUD(模型),我创build一个胖控制器,而不是一个模型? 或者他们说,胖的模式,在回报什么,不打字? 这是我从来没有理解的东西=)任何意见表示赞赏! 非常感谢
OBS1:我没有做什么模型,在控制器中,我只是有方法来控制什么去模型
OBS2:让我们说“checkIfEmailExists()”,有“john@hotmail.com”作为参数。 这个方法将从模型方法返回,如果这个参数存在于表中,则返回boolean。 如果是0,“checkIFemailExists()”会调用一个不同的模型方法,这个方法是他执行Update操作的另一个抽象方法。
OBS3:“checkIfEmailExists()”,不仅仅是一个控制器? 他实际上并没有执行任何CRUD,他只是比较值等。这就是让我感到困惑,因为在我的脑海中,这是一个控制器:S
注:我想这不是最好的例子,因为说“检查是否存在的东西”,听起来像查询我的表操作
问题2:还有一个问题,所以,假设我有一个查看表单,从哪个电子邮件地址参数发送。 你是说这种观点直接模型?
Q3:控制者不应该在他们之间行事? 这就是范式
最后注意:讨论结束了,说我错了,希望没事(我正在学习)。 但是,Q2和Q3的答案是什么?
感谢您的关注
您的应用程序是M.它应该能够独立于V和C. V和C形成用户界面到您的应用程序。 无论是Web界面还是命令行界面,应用程序的核心业务逻辑都无关紧要。 你希望这个模型对于业务逻辑很重要。
如果你有一个胖控制器,例如充满商业逻辑,你不符合MVC的目的。 控制者的唯一责任是处理和委托对模型的UI请求。 这就是为什么它应该是瘦的。 它应该只包含它所负责的代码。
简单的例子
public function fooAction() { if(isset($_POST['bar'])) { $bar = Sanitizer::sanitize($_POST['bar']); $rows = $this->database->query('SELECT * from table'); try { foreach($rows as $row) { $row->foo = $bar; $row->save(); } } catch (Exception $e) { $this->render('errorPage'); exit; } $this->render('successPage'); } else { $this->render('fooPage'); } }
当它应该是
public function fooAction() { if(isset($_POST['bar'])) { $success = $this->tableGateway->updateFoo($_GET['bar']); $page = $success ? 'successPage' : 'errorPage'; $this->render($page); } else { $this->render('fooPage'); } }
因为这是所有的控制器需要知道的。 它不应该更新行。 它应该告诉模型有人要求这个改变。 更新是pipe理行的类的责任。 另外,控制器不一定必须净化该值。
至于第二季度和第三季度,请看我的答案我可以从视图调用模型 。
我一直在与MVC范式工作很长一段时间,我可以与你分享我的经验。
“模型”部分负责处理所有非严格“networking”的东西,如validation,逻辑,数据访问等。将其视为一种混合业务层+数据访问层。 您也可以在单独的程序集中使用BLL + DAL,并使用MVC的“模型”部分作为BLL和您的应用程序之间的桥梁,并添加特定于MVC应用程序且与BLL无关的类,例如ViewData类等等
“控制器”部分是照顾web特定的东西,如身份validation,cookie,GET和POST,查询string等。它使用模型和/或BLL中存在的东西,并发送必须呈现的数据给用户的意见。
“意见”是你的HTML模板,可以从控制器接收数据,并显示它。 任何逻辑操作都不应该在视图中完成,所以没有“if”语句,没有循环等。如果你发现自己有这样的需求,那么你需要一些“帮助器”方法来创build所需的html,然后从视图。 所以视图只接收数据,并向用户提供链接/表单以将数据发布到控制器,但是他们没有详细说明任何内容。
希望这清除了一些你的疑惑。
我一直认为这意味着模型应该以更加面向对象的方式封装与这些模型相关的逻辑,而不是使控制器中的所有逻辑处于更为程序化的方式。 引用大教堂和集市 :
聪明的数据结构和愚蠢的代码比其他方式更好地工作。
我可能会显示我的偏见(朝着C#),但我认为谈论MVC是没有什么意义的,除非您使用的是面向对象的编程风格。 控制器不是一个方法,它是分组到一个类中的方法的集合,每个方法处理一些input(url / request)。 模型不是访问数据库(这是一个数据访问层)的方式,它是一些属性和方法的集合,它们封装了应用程序中的一些可识别的实体:一个人,一个保留,一个产品等。想一想,控制器处理input,模型包含数据 – 但是,当然,这是简化的。
对我来说,“胖”与“瘦”的问题是你的业务逻辑在哪里生存的问题。 如果你的控制器中有很多相关的逻辑,而不是简单地处理input,但是实现业务逻辑,那么你的控制器就比你用它们把请求转换成交付给视图的模型组合。 根据我的经验,这并不总是一个或两个决定。 当你在控制器中拥有应用程序逻辑(权限validation,消毒等)时,很多时候你在模型中有业务逻辑(validation,关系维护,审计)。
我认为一个好的控制器/模型分离可以通过让控制器执行“句法”依赖操作来完成,而不涉及任何/less量业务逻辑,并使用模型执行“语义”相关操作。
这种分离的一个很好的例子是:
您可以在控制器中执行电子邮件的正则expression式检查,但不会在控制器中执行该电子邮件的ldap匹配。