【问题标题】:Understanding controllers in MVC了解 MVC 中的控制器
【发布时间】:2010-12-31 15:42:39
【问题描述】:

我正在构建一个类似于 StackOverflow 的网站,主要是作为一个学习练习,但我很难理解如何决定 MVC 模式中的不同控制器。

究竟什么是控制器?您将使用哪些控制器来模拟类似于 SO 的问答网站?我正在使用 ASP.Net MVC,我注意到 URL 模式始终是“/Controller/Action”——但这绝对不是我希望最终 URL 的样子(“/Question/123”不适合进入该模式)。这是一个考虑因素吗?

我知道这实际上是几个问题的混合......也许我真正需要的是一个很好的教程来理解基础知识。

【问题讨论】:

    标签: asp.net-mvc


    【解决方案1】:

    简单来说,控制器是模型和视图之间的契约/桥梁。

    流程如下:

    控制器用于主请求处理逻辑。如果页面必须与数据库对话, 控制器向模型发送请求,模型使用 db 执行其任务并将一些响应或 db 记录返回给控制器,然后控制器将此响应发送给视图。

    下图更容易解释这个过程:


    (来源:shopno-dinga.com

    【讨论】:

    • 看看heim.ifi.uio.no/~trygver/themes/mvc/MVC-2006.gif 的一位发明者提供的更好的 MVC 图。
    • 模型和控制器之间标记为“数据”的线应该真正在模型和视图之间。控制器操作模型,视图观察模型。
    【解决方案2】:

    让我们把你的问题分成两部分:

    1. Controller 在 Monorail 和 ASP.NET MVC 提供的 MVC 风格中的作用是什么?
    2. url 映射如何与应用程序相关联?

    我对 1 的看法:

    由于这类问题本身就有许多宗教性的答案,我相信这不是“统治所有问题的一种方法”。 现在在 Monorail 和 ASP.NET MVC(当然还有 RoR)中,控制器只是动作的集合。 那么正确的问题是“Action 的作用是什么”?

    在我的书(不成文的 Monorail-in-action book ... :))中,Action 的作用是将域模型与表示分离,无论是在数据结构方面还是在关注点方面。与域的接口是通过 WEB 请求这一事实专用的一切都是控制器的层职责。这包括数据绑定和转换、处理身份验证(但不是授权)以及为视图模板做出决策。 因此,一个动作将从传入请求中获取参数(网络不是一个域关注点),将这些参数绑定到可以作为查询或命令发送到域的有意义的数据,在域的语言,没有 cookie、FORM、QueryString 和其他“网络内容”。 在查看数据时,它还会将从模型返回的域对象转换为视图模型,在前面提到的同一本书中,它是与域模型分离的模型,并负责提供视图-包含所有数据及其所需决策的模板。因此,例如,视图不应该询问 if (view.User.IsAdmin) 并呈现“编辑”按钮,而是控制器的操作会提出这个问题,并为视图提供决定,以便视图询问 if (view.ShouldRenderEditButton)

    因此,控制器层将 WEB 关注点与 DOMAIN 关注点分开。

    至于问题号。 2:

    将 url 映射为 Controller/Action 的想法只是采用“约定优于配置”方法的结果。这意味着,开发人员(和消费者)更容易使用跨不同 Web 应用程序通用的模式。 话虽如此,它不是一成不变的,并且像任何公约一样,它是适应的基础。因此,如果您正在构建一个网站并且产品经理要求提供“漂亮的 url”,那么您只需相应地设置您的路由引擎。

    【讨论】:

      【解决方案3】:

      控制器构成系统边界,即应用程序的 http 接口。它接受一个请求,触发对请求的处理并将结果返回给客户端。

      您可以将属于某一类域对象的所有操作放入单个控制器中。这将导致提到的 URL 模式 /$controller/$action。我建议使用REST。使用 REST,您可以考虑“资源”而不是“控制器”和“操作”。每个资源都有一组通用的方法,即 DELETE、GET、POST 和 PUT。这些方法是 HTTP 动词。与使用非 REST 方法的控制器相比,您将拥有更多资源,但操作的总数将是相同的。

      在您的示例中,一个资源是“问题”,它是所有问题的列表。要创建一个新问题,客户端会发送一个 http 请求,例如“POST /questions $formdata”。将创建一个新的问题对象并将其添加到列表中。客户端将重定向到新创建的问题“redirect /questions/4128”,然后使用“GET /question/4128”加载它。

      简而言之:

      • 每个资源都有一个全局 ID (URL)
      • 每个资源都有一组通用方法(DELETE、GET、POST、PUT)
      • REST 应用程序是无状态的(请求之间没有会话状态)

      好处:

      • 简单
      • 统一;新开发人员易于理解,客户开发人员易于使用
      • 可用于多个客户端,例如浏览器、Feed 聚合器、Web 服务...
      • REST 使用 http 的全部功能而没有开销(与 SOAP Web 服务相比)

      【讨论】:

        【解决方案4】:

        我的看法是,任何你想对它执行操作的东西都需要一个控制器。 因此,例如在 Q/A 网站中可能类似于...

        如果我们用以下实体和关系构建它

        用户

        • 有很多问题
        • 有很多答案

        问题

        • 属于用户
        • 有很多答案

        回答

        • 属于用户
        • 有问题

        然后我们可以让以下控制器处理对上述实体执行的操作。

        • UsersController - 处理用户的创建更新和删除
        • QuestionsController - 处理创建更新和删除 问题
        • AnswersController - 处理创建更新和删除 答案

        你的控制器很可能有比上面提到的更多的方法。

        下一点有点棘手,因为它不仅仅是您想要控制器的模型(以及一些您不想要控制器的模型)。如果您要让用户登录,那么我将创建一个会话控制器来处理登录和注销。

        试着想想你的系统将由哪些实体组成并写下来。然后在这些中,想想你应该对哪些执行操作。然后您可以考虑需要额外的控制器,例如会话控制器。

        进一步注意,模型基本上是系统的对象/实体,控制器使用这些实体执行操作,视图显示模型。

        【讨论】:

          【解决方案5】:

          MVC 架构中的控制器负责向模型请求数据并向视图提供数据。拥有控制器的根本原因是为了保持模型和视图之间的解耦。人们普遍认为,oo 系统中的组件之间的松散耦合或无耦合既是可取的,也是必要的。它支持可重用性和封装性,因此提高了可维护性。

          在 RESTful Web 应用程序的上下文中使用 MVC 模式将支持 处理具有以下格式的 url 的控制器:

          /Controller/Action/:id

          所以要查看一个问题,比如说,您需要:/questions/view/123。可以在here 找到一篇关于设计一个安静的网络应用程序(基于 deli,li,cious)的精彩文章。

          【讨论】:

          • 控制器倾向于在模型上执行操作,其中视图倾向于呈现模型定义的域对象。控制器并不是专门站在视图和模型之间的——如果它只是一个中介,那么你说的是经典的 3 层模型而不是 MVC。
          • 控制器是否也检查输入系统的信息?
          • @D.Shawley - 我认为你正在分裂头发,但你是对的,我没有提到控制器更新模型以及查询它。但是,我会说控制器专门站在模型和视图之间,因为模型和视图很可能直接通信。您不希望这样做的原因是保持解耦。实现控制器(主持人)的解耦结果。
          • 在这种情况下,我不认为我是 分叉。 n 层和 MVC 之间有一条非常细的界线。看一看原始 MVC 论文之一 (heim.ifi.uio.no/~trygver/1979/mvc-2/1979-12-MVC.pdf) - “视图附加到其模型(或模型部分)并通过提问从模型中获取演示所需的数据”。该视图与呈现模型的过滤子集有关。控制器提供了操作模型定义的域对象的逻辑。
          【解决方案6】:

          很多人发现这个讨论很有帮助:

          What goes into the “Controller” in “MVC”?

          【讨论】:

            【解决方案7】:

            据我所知,这主要是偏好。我曾经问过自己同样的问题,但发现控制器只是将视图和模型组合在一起以有序的方式呈现信息。

            我认为您可以有一个 Questions 控制器,具有 View、Edit、Create 等方法。这似乎很有意义,尤其是对于项目 - 一个问答网站。

            【讨论】:

              猜你喜欢
              • 2013-01-05
              • 2013-04-08
              • 2012-11-04
              • 2011-07-11
              • 1970-01-01
              • 2013-12-05
              • 2013-10-14
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多