MVC 设计模式。 View如何适应它?

Posted

技术标签:

【中文标题】MVC 设计模式。 View如何适应它?【英文标题】:MVC design pattern. How does View fit it? 【发布时间】:2013-01-20 23:08:06 【问题描述】:

我对模型-视图-控制器设计模式有疑问。我了解模型保存数据。我也了解控制器(View Controllers)实现应用程序的逻辑。例如,如果 UIPicker 轮选择第 4 行,则视图控制器可以向模型询问存储在模型数组中的第 4 个对象。我无法理解“视图”是否适合。我认为该笔尖/情节提要文件将被归类为“视图”。但是,每个视图都需要连接视图控制器以将所有出口连接到视图。我应该如何保持 View 和 View Controller 分开?在实现这些插座的逻辑时,我是否应该将所有插座连接到“视图类”,然后在我的视图控制器中引用我的“视图”类?也许我只需要一个 View 和 View Controller 处理不同任务的示例。因为否则额外的“视图”类似乎没有意义。 MVC的View是指一个View Class吗?我希望如何或为什么要将这个 View Class 从我的 View Controller 类中分离出来?

【问题讨论】:

【参考方案1】:

视图的工作是显示数据和报告事件。

控制器的工作是协调视图和模型之间的通信。

数据的工作是存储数据并围绕该数据提供业务逻辑。

你问:

我无法理解“视图”是否适合。

在您的示例中,UIPickerView 是视图。

ios/OSX 中,视图控制器只是 MVC 的控制器。碰巧视图控制器还包含一个空视图容器,您可以将所有其他视图添加到该容器中。但是在 iOS/OSX 中,MVC 还是有明显的分离。

UIButtonUIPickerViewUITableView 等所有类都代表视图。视图控制器的工作是为这些视图提供来自数据模型的数据,并响应来自这些视图的事件,让您有机会更新其他视图和数据模型。

你还说:

然而,每个视图都需要连接一个视图控制器来将所有出口连接到视图。我应该如何将 View 和 View Controller 分开?

它们是分开的。如果添加UITableView,那是一个单独的视图。您将它连接到一个类,以便该类可以实现数据源和委托方法。该类是控制器类。这个控制器类通常是一个视图控制器,但它不是必须的。您可以编写独立于任何特定视图控制器(或通用控制器)的各种自定义视图类。但最终该视图类需要连接到 [视图] 控制器类,以便正确处理数据和事件。

你问:

我希望如何或为什么要将这个 View Class 从我的 View Controller 类中分离出来?

看看UITableViewController。这是一个明显的分离示例,但它是在一个相当整洁的包中提供的。您实际上有一个单独的 UITableView 类,即视图。该视图负责呈现视图并收集用户交互。它是实际的表视图控制器,它向视图提供数据并处理来自视图的用户事件。

您可以将UITableView 视图添加到任何视图。这是一个完全可重用的视图组件。您连接到表视图的每个控制器都可以提供任何适当的数据并正确处理用户交互。

【讨论】:

哇,谢谢您的详尽回答!我觉得这是回答我问题根源的最具体的 iOS 答案。您说 View Controller 是控制器对象(而不是控制器和视图对象的混合)。您说视图是情节提要/ xib 文件附带的空白视图上的对象层次结构。我想我在想如果没有特定的单独类,“视图”对象就不存在。很多时候,“视图”对象似乎不需要单独的类。然而,某些视图(如表格视图)需要视图类(如表格单元格视图)。 您拖到情节提要或视图控制器上的每个小部件都是一个单独的视图类。当您在代码中执行所有操作时,这一点会更加明显。 谢谢!这个答案肯定会得到一个复选标记。这清楚了很多。没有不尊重其他回答的人,但我想我应该说我正在使用 xcode 进行 iOS 开发。我很惊讶术语视图控制器对某些人来说是个谜——但我猜 MVC 适用于不使用视图控制器对象的不同语言。 MVC 是一种独立于任何编程语言的通用设计模式。用各种不同语言编写的各种框架都支持 MVC 模式。 很好的解释,麦迪!!但是,我想更多地了解用于存储数据的“模型”部分。如何设计这些模型?理想情况下应该是什么样的课程?【参考方案2】:

好的,我会试着整理一下。

该模式称为模型-视图-控制器,从而将模型、视图和控制器明确分离。正如您正确指出的那样, ViewController 将事物放在一起(来自 View 和 Controller :),实际上 ViewController 打破了强大的 MVC 模式。好消息是:如果您使用 ViewController,则不必将视图和控制器分开(猜猜它为什么这样命名?)。

现在我对设计为何如此简单的解释:

当您将 View 和 Controller 严格分开时,您基本上可以获得良好设计的学分。然而,事实证明,他们两个并不像我们希望的那样分开。不同的 GUI 表示通常确实需要不同的视图实现以及控制将模型转发到 GUI 的控制器的适配,例如在控制台上显示纯文本与在位图上绘图。在第一种情况下,您的控制器会将一个字符串传递给要渲染的视图,在第二种情况下,它还需要设置一些坐标才能将文本渲染到正确的位置。因此,您的控制器会经常更改。

理想的情况是实现模型和控制器,并简单地为任何人在现实生活中看到的任何东西提供视图。然而,在现实生活中,控制器很可能会适应视图,而不会单独使用模型。因此,将视图和控制器组合到包含特定视图并知道如何使用它的 ViewController 的设计决策只是一种合理的方式。

【讨论】:

谢谢。如果我理解正确的话,在使用视图控制器时,我很可能会使用模型 - 视图控制器模式而不是 M-V-C 模式。根据我的应用程序的复杂性,这可能是好是坏。因此,如果我想使用 M-V-C 模式,当将 ViewController 对象拖到我的故事板上时,我会将其类更改为自定义 View 类。我将为我的模型创建另一个类,为我的控制器创建另一个类。这将使事情保持清洁,我不会想用 ViewController 弄脏我的设计模式。 @tereško 不,没有。然而,正如最初的问题所暗示的那样,主题是 iOS/OSX 开发(这就是 ViewController 的来源),我只是试图解释为什么设计师在传播 MVC 时选择了这个概念。 @RyanBittorf 没错。如果您可以设法将控制器与您的视图清楚地分开 - 去吧。但是,请记住,“ViewController”习语深深地嵌套在 Cocoa 开发中——因此 VC 会做很多你必须手动实现的事情(例如旋转视图......) @tereško 实际上,如果您仔细阅读,您会在我的第二句话中对问题进行澄清。【参考方案3】:

其实你的理解是完全错误的。

MVC 设计模式背后的核心原则是Separation of Concerns。您将模型层与表示层分开,并且(在表示层中)将视图与控制器分开。

每个pars都有不同的职责:

模型层包含所有的业务逻辑。这包括与存储、域逻辑和应用程序逻辑的交互。 view 负责 UI 逻辑。在 Web 上下文中,这意味着该视图处理为用户创建响应 控制器是接受用户输入的部分,并在此基础上改变模型层和当前视图的状态。

人们倾向于对 MVC 存在很多误解。例如:

    有些人会坚持认为视图是愚蠢的模板。他们不是。

    MVC 设计模式中的视图是功能齐全的实例,处理可能使用也可能不使用多个模板来生成响应。

    没有“模型”。模型是一个层,由多个不同的类组组成,每个类都有特定的任务。与表示层没有“表示”对象的方式相同

    控制器不会将数据从模型层发送到视图。控制器只改变三元组其他部分的状态。视图实例本身从模型层请求他们需要的东西。

【讨论】:

您应该记住,问题不仅仅与 MVC 模式有关。它是关于 MVC 模式在现实环境中的应用(即 iOS - 阅读正文!)。它可能被标记错误,但请使用您的常识【参考方案4】:

为了回答您的问题,让我们分解 MVC - 模型、视图、控制器。什么去哪里?

模型通常被认为是“做某事”层。这包含业务逻辑和数据逻辑。您的模型应该是 FAT,而不是 SKINNY,这意味着您的模型中应该有很多代码。

Controller,我认为是“响应”层。这是您决定向用户返回什么的地方,无论是视图还是其他类型的响应,例如 JSON(在 RESTful 响应中特别有用)。您也可以使用模型,但您不应该在控制器本身中构建太多逻辑。你应该有一个 SKINNY 控制器。

视图主要是页面的标记——html 以及其他用于访问模型的标记——这取决于您使用的框架。我的经验是使用 MVC .NET,所以我会使用它。与 HTML 混合后,您将访问模型元素。视图中不应该有任何真正的逻辑,但你可以做一些事情,比如(使用 Razor 语法)

<div>@foreach person in Model.Users
    <p>@person.FullName</p>

</div>

因此,您可以看到视图可以有一些“显示逻辑”(例如,遍历人员并获取 FullName),但这就是您真正应该拥有的一切。

这是一个快速幻灯片,它解释了有关 MVC 的更多信息,包括为什么您最初对“模型保存数据,控制器保存逻辑”的解释实际上是不正确的:http://www.slideshare.net/damiansromek/thin-controllers-fat-models-proper-code-structure-for-mvc

MVC 设计模式不包含任何称为“ViewController”的东西,它来自其他地方。

【讨论】:

James - 我正在使用 Xcode 在 Objective C 中构建 iOS 应用程序。当以图形方式构建视图时,使用的对象称为视图控制器。还有表格视图控制器等。在启动项目时,您会看到一个空白视图控制器和一个视图控制器类。每个人都教使用视图控制器构建 iOS。这些人还宣扬 M-V-C。在演示构建应用程序时,事物与视图控制器融合在一起 经过短暂的谷歌搜索后,看起来 ViewController 是一种“增强型控制器”,您可以使用它来管理多个视图。我必须指出,这仍然不是我在上面发布的传统 MVC 模型的一部分,这是不同的东西。 MVC 对很多人来说意味着很多东西,但我解释的标准接受方式。

以上是关于MVC 设计模式。 View如何适应它?的主要内容,如果未能解决你的问题,请参考以下文章

如何组织游戏代码以适应 MVC 模式?

什么是MVC设计模式,如何使用MVC

服务层和数据访问对象层如何适应 Spring MVC 架构?

了解 MVC 模式

具有适应不同屏幕分辨率的视图的 MVC 模式

iPad的自适应布局