Apple的Cocoa框架的设计模式:MVC,MVP,被动视图...... Apple在哪里?

时间:2008-12-09 17:57:13

标签: cocoa design-patterns

为这个问题奠定基础,我将说明我从以下内容获得MVC,MVP和Passive View的定义:

Model View Controller (MVC)
Model View Presenter (MVP)
Passive View (PV)

Apple一直声称它使用MVC设计模式,但我注意到在OS X 10.5中我们已经获得了NSViewController,KVO,绑定等等,这些对象看起来更像是被动视图设计模式。这是苹果希望我们前往的地方吗?我希望以尽可能与Apple选择的设计模式一致的方式规划我的代码,这就是为什么我想知道Apple的目标。有没有人有线索?

6 个答案:

答案 0 :(得分:7)

任何复杂的代码都有很多可能适用不同模式的地方。 MVC在Cocoa文档中非常突出,因为它解释了您的功能代码(模型),UI代码或IB设计(视图)与将它们连接在一起的Cocoa服务(控制器)之间的关系。这是值得强调的,特别是在介绍性的dox中,因为你需要一点“警醒”来停止认为你必须自己编写它,并开始考虑如何设计你的独特部分,并相信框架来做它管道工作。

MVC的变体定义具有传奇色彩,值得指出的是MVC没有在规范的“四人帮”一书“设计模式”中描述。同样值得承认的是,Cocoa的“MVC”模型与SmallTalk 80 MVC(术语所源自的地方)并不相同。

可能还值得指出的是,“GoF”实际上使用“模式”一词来表示特定的文档样式,而不是设计模式所描述的代码的抽象方式。太糟糕了,这种用法已经大部分丢失了。如果我们都这样理解这个词,那么我可以说“如果有人真的为Cocoa的MVC编写一个模式,那将会非常有用。”然后我们不会都这么困惑!

答案 1 :(得分:4)

Cocoa 基于MVC (作为Apple defines it),并且一直在为您做越来越多的趋势。这是目前的情况。

  • 查看图层:NSView,NSWindow,NSCell,他们的子类和CALayer
  • 控制器层(自10.3起):NSController和子类(主要是NSArrayController)
  • 模型层:传统上,您必须完全自己完成此操作,但自10.4以来,您可以使用Core Data。

绑定由KVO(和KVC)提供动力,并且是将三层绑定在一起的胶水。将视图绑定到控制器,将控制器绑定到模型。

答案 2 :(得分:3)

我不会说Cocoa遵循其所描述的被动视图模式。它说控制器在准备视图和发送更改通知时完成所有工作。在Cocoa中,视图对象通常会响应模型中的KVO通知(通过绑定),刷新绑定到的控制器的数据,通过数据格式器或值变换器进行准备,最后在屏幕上显示。

Cocoa很好地遵循MVC,尽管通常“控制器”方面分为视图控制器和模型控制器。您可以阅读有关此here的更多信息。如果你有任何关于你感到困惑的具体例子,也许我可以提供关于Cocoa做事的更多细节。

在同一指南中,this section解释了一些您可能会觉得有用的其他设计模式。根据我自己的经验,虽然经过一些项目后,Cocoa的MVC很自然地来了,我不会太在意它。

答案 3 :(得分:2)

我认为Cocoa / OpenStep并没有真正遵循MVC,例如,SmallTalk 80。 SmallTalk Controller实际上是负责解释用户与View的交互,在Cocoa的情况下由NSControl处理,因此由View层处理(也许它在框架内以这种方式分解,但我们不应该在里面偷看;这就是抽象的全部:-)。与你的那些链接相关,Cocoa中的Controller层确实属于Presenter标题,特别是在考虑Cocoa Bindings的各种NS * Controller类时。那些真的是视图层和模型之间的穿梭。

在我自己的应用程序中,我倾向于有四个不同的层,即使它们没有明确分开;视图,演示者,服务和模型。然后,“演示者控制器”和“服务控制器”具有完全不同的目的;逻辑和进程在服务中,工作流和用例在视图控制器中。在包装方面,如果您涉及到这种类型的东西,那么服务和模型一起代表了一个抽象的“关于东西的事情”,它可以与上下文无关。演示者和视图代表“这就是Mac OS X应用程序的用户希望如何使用它”,这取决于较低的包,并封装了AppKit特定的(和特定于AHIG的)类和行为。

答案 4 :(得分:2)

苹果文档实际上解释了MVC比我读到的任何其他内容更好。基本上与MVC相关的混淆是因为它是复合模式。它由许多基本模式组成。虽然 Gang of four 设计模式中没有讨论MVC,但基本模式是。

  

我认为的主要区别在于   控制器是Apple的世界   中介模式除了什么   通常是。

     

与传统方法不同   Apple的世界中的模型不会通知   改变观点。他们不通知   事实上任何人。如果你想改变   你需要通过的模型   控制器,以确保每个人都是   通知变更。

我认为这种方法比传统方法好得多。它对模型对象没有任何限制。他们不必实现任何特定的接口。他们只需要解决特定领域的问题。因此,您可以在其他应用程序中轻松地重用它们。

主要是控制器对象必须在这种方法中重写。当然,Apple通过绑定改变了这一点。但是,如果您不使用绑定,则控制器是特定于应用程序的。

在C ++中使用Apple MVC

在使用Qt在C ++中编写应用程序时,我实际上遵循了Apple的设计。视图是QWidget的。我将所有与外观有关的代码放在QWidget子类中。然后我让我的控制器成为一个QObject子类,让它创建视图对象,并将来自QWidgets的信号连接到我的QObject控制器中的插槽。我的模型类是一个常规类,它不会从Qt继承任何东西并实现业务逻辑。它会被控制器插槽修改。

或者,QWidgets可以在控制器之外创建,因此您可以将控制器重用于其他类型的视图。

不确定这对任何人是否有帮助,但我认为有时候用C ++来考虑Cocoa模式会更容易,因为我们习惯于用静态类型语言(如C ++和Java)来解释模式。

答案 5 :(得分:1)

糟糕, MVC =有史以来最错误的模式。我已经阅读了至少5种不同的定义。

您可能希望通过Martin Fowler

阅读本文