【问题标题】:Controller vs. Model - Need explanation控制器与模型 - 需要解释
【发布时间】:2011-06-07 01:58:25
【问题描述】:

我正在开始我的“学习 MVC”方式。基本上,我对面向对象编程没有什么大问题,但是有一个技术方面需要澄清。看来我的理论还不够好。

目前,我使用的是 KohanaPHP 框架,版本 3。

示例情况: 我有一个网站,用户可以在其中提交文章。

所以我有以下结构:

classes/
    /controllers/
        article.php
    /models/
        articles.php

到目前为止一切顺利。我对扩展 Kohana_Model 的模型没有任何问题,但是我不确定我是否使用了使用 ORM 的正确方式的模型。

基本上,当使用扩展 Kohana_Model 的模型时,我会将所有逻辑操作放在模型中。我应该对使用 ORM 的模型做同样的事情吗?在网络上的许多示例中,我看到控制器正在对来自数据库的用户输入/数据执行逻辑操作,这在我看来是不正确的。

假设我需要从数据库中获取几行,所以我在模型中创建了正确的方法并返回了对象。我认为它是正确的,不是吗?

基本上,对用户输入/数据的所有操作(从数据库中选择、插入数据库、验证)我都放入模型中。这就是我理解 MVC 设计模式的方式。模型应该关心所有“机械”操作,控制器只是模型/视图之间的“桥梁”,它是一个“前端”引擎。

这是一个正确的方法吗?

我知道对于更高级的用户来说这可能是一个愚蠢的问题,但我只想学习好的做法。如果有人能提供一些澄清,我会很高兴。

【问题讨论】:

标签: php model-view-controller design-patterns orm hmvc


【解决方案1】:

简而言之,您的模型对数据执行所有操作(无论是传入、传出、数据库、文件...数据),并且您的视图应该负责显示数据。控制器应该调用必要的模型方法来准备好传递给视图的数据。控制器不应对数据执行任何更改,但应对其进行测试以正确完成必要的操作。

希望我已经说得够清楚了,如果这对你来说还不够清楚,请告诉我。

【讨论】:

  • 这正是我进一步了解模型和控制器之间差异所需的简明答案。谢谢。
  • 感谢这个。现在我知道控制器或模型中应该有哪些方法了。
  • 控制器不应对数据执行任何更改,但应对其进行测试以正确完成必要的操作。如果我没听错……我们应该在我们的控制器上执行数据验证?
  • @iamjoshuamabina 从我的角度来看,应该在填充模型/控制器时完成实际的数据验证,如果失败,那么控制器应该根据失败的情况采取必要的措施。所以换句话说,实际的验证代码是在模型/集合内部完成的,但是控制器负责决定接下来会发生什么和/或调用模型/控制器验证方法来检查数据。
  • 按照我的理解,控制器是数据(模型)和用户所见(视图)之间的中间人。
【解决方案2】:

我没有使用过 KohanaPHP,但它看起来像是一个“受 Rails 启发”的框架。 在 Rails 世界中,拥有瘦控制器和胖模型通常被认为是最佳实践。

一些背景可以在jamis buck http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model的这篇旧文章中找到,或者在这个关于cakephp http://gluei.com/blog/view/cakephp-best-practices-fat-models-and-skinny-controllers的文章中找到

【讨论】:

  • 感谢您的回答。我会选择 poelinca 的答案为正确的(你也是正确的),但你得到了更多的分数 ;-)
【解决方案3】:

将逻辑与数据分离的想法是数据不包含逻辑,因此在您的模型中,您应该只真正清理数据。

举个例子:

public class Articles extends MasterModelLayer
{
    public function create($title,$text,$user_id = false)
    {
        if(!$user_id)
        {
             $user_id = get_guest_id();
        }
        //Insert
    }
}

模型中的逻辑似乎是合法的,但从现在开始,您的应用程序必须能够允许访客发布文章,否则它存在缺陷,您需要编辑模型,这将影响您网站的其他应用程序/区域

以这个场景为例:

您有 2 个网站

  • ComputerArticles.com
  • CookingArticles.com

现在这两个域指向同一个服务器,但在 kohona 中是一个单独的应用程序,不要在您的模型中放置任何域逻辑,您可以在所有域中使用精确的示例模型。

您的模型方法应如下所示:

public class Articles extends MasterModelLayer
{
    public function create($title,$text,$user_id)
    {
        $this->compile("articles",array($title,$text,$user_id))->insert();
    }
}

在您的控制器中,您应该放置所有逻辑,因为逻辑将取决于域。

将您的模型视为一个 API,您有多个站点使用相同的 API,但逻辑不同。

希望这会有所帮助。

【讨论】:

    【解决方案4】:

    以下是术语的基本外行定义 - 视图:呈现给用户的屏幕 控制器:一个引擎/框架,它接收请求,确定谁处理它并适当地委派它们。 模型:这基本上告诉你在这个屏幕上执行某某操作后要显示什么屏幕。将其视为(有向)图。从节点出现的边是动作,它们连接的节点是基于这些动作的下一个屏幕。

    所以模型基本上包括用户在屏幕上执行的操作及其操作处理程序。控制器只需为特定的用户操作调用相应的操作处理程序,操作处理程序负责对传入的请求做一些有意义的事情。

    现在你的问题。业务逻辑去哪儿了? 好吧,它是动作处理程序。或者它被抽象到人们喜欢称之为业务层的地方。但无论如何,它是从动作处理程序本身触发的。

    因此,从技术上讲,业务逻辑是操作的一部分,而操作本身就是模型的一部分。 如果您这样想,这是有道理的:控制器处理用户交互并根据模型(操作 + 业务)呈现视图。

    ** 错别字已更正。

    【讨论】:

      猜你喜欢
      • 2011-11-01
      • 2022-01-20
      • 2018-06-21
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 2015-02-16
      • 2019-11-08
      • 1970-01-01
      相关资源
      最近更新 更多