【问题标题】:Design patterns for Apple's Cocoa frameworks: MVC, MVP, Passive View... where is Apple heading?Apple Cocoa 框架的设计模式:MVC、MVP、Passive View……Apple 将走向何方?
【发布时间】:2014-05-08 03:19:49
【问题描述】:

为了为这个问题打下基础,我将声明我的 MVC、MVP 和被动视图的定义来自以下:

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

Apple 一直声称它使用 MVC 设计模式,但我注意到在 OS X 10.5 中我们获得了 NSViewController、KVO、绑定等对象,这些对象的行为似乎更像 Passive View 设计模式。这是苹果希望我们去的地方吗?我想以一种尽可能与 Apple 选择的设计模式配合使用的方式来规划我的代码,这就是为什么我想知道 Apple 的发展方向。有人知道吗?

【问题讨论】:

  • 似乎有些人认为我对 MVC、MVP 和 PV 术语感到困惑;别担心,我不是! :) 我只是想知道 Apple 是否正在慢慢向 PV 设计模式转变,但没有将名称从 MVC 更改为 PV。对我来说,感觉就像是(旧代码是 MVC,新代码是 PV)

标签: cocoa design-patterns


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    Cocoa基于MVC的(如Apple defines it),一直以来都有为你做更多的趋势。这是目前的情况。

    • 视图层:NSView、NSWindow、NSCell、它们的子类和CALayer
    • 控制器层(从 10.3 开始):NSController 和子类(主要是 NSArrayController)
    • 模型层:传统上,这必须完全由您自己完成,但从 10.4 开始,您或许可以使用 Core Data。

    绑定由 KVO(和 KVC)提供支持,是将三层绑定在一起的粘合剂。您将视图绑定到控制器,将控制器绑定到模型。

    【讨论】:

      【解决方案3】:

      我不会说 Cocoa 遵循那里描述的被动视图模式。意思是控制器完成了准备视图和发送更改通知的所有工作。在 Cocoa 中,视图对象通常会响应来自模型的 KVO 通知(通过绑定),从绑定的控制器刷新数据,通过数据格式化程序或值转换器进行准备,最后将其显示在屏幕上。

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

      在同一指南中,this section 解释了一些您可能会觉得有用的其他设计模式。以我自己的经验,虽然在完成了几个项目之后,Cocoa 中的 MVC 往往会很自然地出现,我不会太在意它。

      【讨论】:

      • 我很欣赏这些链接,但我并没有对这些模式感到困惑;我只是想看看苹果是否正在朝着不同的模式转变。新的框架/模式(在我看来)似乎是被动的,我想与其他人验证这是否属实。不过谢谢!
      【解决方案4】:

      我认为 Cocoa/OpenStep 从未真正遵循 MVC,例如 SmallTalk 80 中所描述的那样。 SmallTalk 控制器实际上是负责解释用户与 View 的交互,在 Cocoa 的情况下,由 NSControl 处理,因此由 View 层处理(也许它在框架内以这种方式分解,但我们不应该这样做窥视内部;这就是抽象的全部内容:-)。关于您的这些链接,Cocoa 中的 Controller 层确实属于 Presenter 旗帜,特别是在考虑 Cocoa Bindings 中的各种 NS*Controller 类时。这些确实是视图层和模型之间的穿梭。

      在我自己的应用程序中,我倾向于有四个不同的层,即使在它们没有明确分开的地方也是如此;视图、演示者、服务和模型。那么“presenter controllers”和“service controllers”有完全不同的目的;逻辑和流程在服务中,工作流和用例在视图控制器中。在打包方面,如果你喜欢这种事情,服务和模型一起代表了一个抽象的“对事物做的事情”,它可以是与上下文无关的。演示者和视图代表“这就是 Mac OS X 应用程序的用户想要使用它的方式”,它依赖于较低的包,并封装了 AppKit 特定(和 AHIG 特定)的类和行为。

      【讨论】:

        【解决方案5】:

        Apple 文档实际上比我读过的任何其他文档都更好地解释了 MVC。基本上与 MVC 相关的混淆是因为它是一种复合模式。它由许多基本模式组成。尽管四人组设计模式中没有讨论MVC,但基本模式是。

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

        因此与传统方法不同 苹果世界中的模型不通知 变化的看法。他们不通知 事实上任何人。如果你想改变 一个模型,你必须通过 控制器以确保每个人都 通知更改。

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

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

        在 C++ 中使用 Apple MVC

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

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

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

        【讨论】:

        • “因此,与 Apple 世界中的传统方法模型不同,它不会通知变化的视图” - 嗯,是的,它们确实如此 - 这正是它的工作方式。
        【解决方案6】:

        呃-哦。 MVC = 有史以来最错误引用的模式。我已经阅读了至少 5 种不同的定义。

        您可能想阅读Martin Fowler 的这篇文章

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-01-27
          • 2023-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-03
          • 1970-01-01
          相关资源
          最近更新 更多