MVC 设计模式。视图如何适配?

8
我对模型-视图-控制器设计模式有些疑问。我知道模型保存数据,也知道控制器(视图控制器)实现应用程序的逻辑。例如,如果UIPicker轮选择第四行,则视图控制器可以向模型请求存储在模型数组中的第四个对象。但是我不太理解“视图”应该放在哪里。我认为nib / storyboard文件应该被归类为“视图”。然而,每个视图都需要连接一个视图控制器,以将所有输出线路连接到视图上。我应该如何保持视图和视图控制器分离?我是否应该将所有输出线路连接到“视图类”中,然后在我的视图控制器中引用我的“视图”类来实现这些输出线路的逻辑?也许我只需要一个示例,其中视图和视图控制器处理不同的任务。否则,额外的“视图”类似乎没有意义。MVC中的“视图”是指“视图类”吗?我为什么要将此“视图类”与我的“视图控制器类”分开?
4个回答

14

视图的职责是显示数据并报告事件。

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

数据的任务是存储数据,并为该数据提供业务逻辑。

你问道:

我有些困惑“Views(视图)”在哪里适用。

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

在iOS/OS X中,视图控制器只是MVC的控制器。恰好视图控制器还包含一个空视图容器,您可以将所有其他视图添加到其中。但是,在iOS/OS X中仍存在明确的MVC分离。

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

您还说:

然而,每个视图都需要连接一个View Controller以线路上所有出口到视图上。我如何保持视图和视图控制器分开呢?

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

您问道:

我如何或为什么要将此View Class与我的View Controller Class分开?

看一下UITableViewController。这是一个很清晰的分离示例,但它提供了一个相当整洁的包。实际上,你有一个单独的UITableView类作为视图。这个视图负责呈现视图并收集用户交互。而实际的表视图控制器则提供数据给视图,并处理来自视图的用户事件。

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


1
哇,谢谢你详细的回答!我感觉这是最针对我的问题的iOS特定答案。你说View Controller是控制器对象(而不是控制器和视图对象的混合体)。你说视图是带有Storyboard / xib文件的空白视图上的对象层次结构。我认为如果没有一个特定的单独类来表示它,我就认为“View”对象不存在。看起来很多时候“View”对象不需要单独的类。然而,某些视图(如表视图)需要视图类(如表格单元视图)。 - iOSAppGuy
每个你拖放到故事板或视图控制器上的小部件都是一个独立的视图类。当你在代码中完成所有操作时,这一点就更加明显。 - rmaddy
谢谢!这个答案肯定会得到勾选。这解决了很多问题。没有不尊重其他回答者的意思,但我认为我应该声明我正在使用Xcode进行iOS开发。我很惊讶术语“视图控制器”对一些人来说是个谜 - 但我猜MVC适用于不使用视图控制器对象的不同语言。 - iOSAppGuy
MVC是一种通用的设计模式,与任何编程语言无关。使用不同编程语言编写的各种框架都提供对MVC模式的支持。 - rmaddy
很好的解释Maddy!但是,我想了解更多关于用于存储数据的“模型”部分。如何设计这些模型?理想情况下应该是什么样的类? - Rashmi Ranjan mallick

1

好的,我会尽力梳理一下。

这个模式被称为模型-视图-控制器,因此清晰地分离了模型、视图和控制器。正如您所指出的那样,视图控制器将它们组合在一起(来自视图和控制器 :)),实际上视图控制器打破了强MVC模式。好消息是:如果您使用视图控制器,您不必分离视图和控制器(猜猜为什么它被命名为这样?)。

现在是我关于为什么设计是这样的的新手解释:

当您严格分离视图和控制器时,您基本上为良好的设计赚取信用点。然而,事实证明,它们两者并没有像我们希望的那样分离。不同的GUI表示通常需要不同的视图实现以及控制器的调整,以控制模型向GUI的转发,例如在控制台上进行纯文本显示与在位图上进行绘制。在第一种情况下,您的控制器会将一个字符串传递给视图进行渲染,在第二种情况下,它还需要设置一些坐标,以便将文本渲染到正确的位置。因此,您的控制器将经常更改。

理想情况下是实现模型和控制器,并为任何人在现实生活中看到的内容提供视图。然而,在现实生活中,控制器很可能会适应视图,而不影响模型。因此,将视图和控制器组合成一个ViewController的设计决策是一个合理的选择,其中包含特定的视图并知道如何使用它。

如果我理解正确的话,当使用视图控制器时,我很可能会使用模型 - 视图控制器模式而不是M-V-C模式。这可能是好的或者坏的,这取决于我的应用程序的复杂性。所以,也许如果我想采用M-V-C模式,在将ViewController对象拖动到我的Storyboard时,我会将它的类更改为自定义视图类。我将再创建一个模型类和一个控制器类。这将使事情保持清洁,我不会被诱惑用视图控制器来弄脏我的设计模式。 - iOSAppGuy
2
@tereško 没有。然而,正如原问题所示,该主题是iOS/OSX开发(那就是ViewControllers来自的地方),我只是试图解释为什么设计师在传播MVC时选择了这个概念。 - cli_hlt
@RyanBittorf 没错。如果你能够清晰地将控制器与视图分离 - 那就去做吧。但是,请记住,“ViewController”惯用语在Cocoa开发中嵌套很深 - 因此VC会做很多你否则需要手动实现的事情(例如旋转视图...) - cli_hlt
2
@tereško 其实,如果您仔细阅读,您会在我的第二个句子中看到对问题的澄清。 - cli_hlt

1

实际上,你所理解的完全是错误的。

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

这三个部分各自负责不同的职责:

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

人们在 MVC 模式方面存在许多误解,人们往往会在传播这些误解。例如:

  1. 有些人会坚称视图是愚蠢的模板。但它们不是这样的。

    MVC 设计模式中的视图是完全功能的实例,可能使用一个或多个模板生成响应。

  2. 没有“模型”这个概念。模型是一个层,由多个不同组的类组成,每个组都有特定的任务。就像表示层没有“表示”对象一样。

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


1
你应该记住,这个问题不仅仅涉及到MVC模式。它涉及到在现实世界中(即iOS - 请阅读文本!)应用MVC模式。它可能被标签错误,但要运用常识。 - cli_hlt

0

好的,为了回答你的问题,让我们来分解MVC - 模型(Model),视图(View),控制器(Controller)。它们应该放在哪里?

模型(Model)通常被认为是“执行某些操作”的层。这个层包含业务逻辑和数据逻辑。你的模型应该是FAT而不是SKINNY,也就是说,你应该把大部分代码都放在模型中。

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

视图(View)主要是页面标记 - HTML以及其他获取模型访问权限的标记 - 这取决于你使用的框架。我的经验是使用MVC .NET,所以我会以此为例。在HTML中混合了模型元素的访问。视图中不应该有任何真正的逻辑,但你可以做一些事情,比如(使用Razor语法)

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

所以你可以看到,View 可以有一些“显示逻辑”(例如,循环遍历人员并获取 FullName),但这就是你应该放在那里的全部内容。

这是一个快速幻灯片,更详细地说明了 MVC,包括为什么你最初的“Model 持有数据,Controller 持有逻辑”的解释实际上不正确:http://www.slideshare.net/damiansromek/thin-controllers-fat-models-proper-code-structure-for-mvc

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


詹姆斯 - 我正在使用Xcode用Objective C构建iOS应用程序。在图形化构建视图时,使用的对象称为视图控制器。还有表视图控制器等。启动项目时,您会看到一个空白的视图控制器和一个视图控制器类。每个人都教授使用视图控制器构建iOS。这些人也宣扬M-V-C。在演示构建应用程序时,视图控制器的内容混合在一起。 - iOSAppGuy
经过简短的谷歌搜索,似乎ViewControllers是一种“增强控制器”,您可以使用它来管理多个视图。我必须指出,这仍然不是传统MVC模型的一部分,这就是我上面发布的内容,这是不同的东西。 MVC对于不同的人意味着许多事情,但标准接受的方式就是我所解释的。 - James M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接