1

今天我对软件设计模式有了一些新的认识。
特别是我想知道MVCThree-tier-layer之间的区别。基本上,根据我在 wikipedia 和其他来源上阅读的内容,两者之间的主要区别在于组件交互:

三层架构中的一个基本规则是客户端层从不直接与数据层通信。

同时

... MVC 架构是三角形的:视图向控制器发送更新,控制器更新模型,视图直接从模型更新

现在:如果我们看一下关于这个问题的苹果文档,我们会看到:


在此处输入图像描述

他们明确表示 Views 和 Model 不应该直接通信:

视图对象通常与 MVC 应用程序中的模型对象分离

当模型对象发生变化时(例如,通过网络连接接收到新数据),它会通知控制器对象,控制器对象会更新相应的视图对象

等等。那么,这是怎么回事?Cocoa 是否采用了自己的 MVC 理念,而不考虑常见的?还是我在查看 MVC 架构的常见方式中遗漏了一些东西?

4

2 回答 2

1

虽然可以说 Cocoa 版本的 MVC 是 MVC 实际定义的一种子集,但它们并不是独立的实体。MVC 的 Cocoa 版本通常围绕使用视图(通常是一个NSWindow和/或一个NSView)、一个控制器(通常是一个NSWindowController)和一个模型层(从简单的数组到核心数据堆栈的任何东西)。该模型中的权力分立很明确,但 Wiki 定义的“层级”结构中的每一个都应该属于哪一个呢?

我认为控制器和视图是客户端层的一部分。控制器不仅负责模型和视图之间的委托,还负责响应用户事件并确定在非框架错误处理期间要采取的正确行动方案。通过对 MVC 采用这种方法,您现在可以开始了解 Cocoa 实际上是如何满足更广泛的模式定义的。

三层架构中的一个基本规则是客户端层从不直接与数据层通信。

这可能是 3 个中最难推理的,它涉及深入研究“通信”在模式上下文中的实际含义。当我们说通信时,我们的意思是控制器没有直接参与模型所采取的行动。这并不是说控制器不能命令更改模型的内容,而是说控制器无法控制模型如何自我更新。控制器充当指挥者,而不是实现者,这极大地简化了数据库层的创建,这也是 Core Data 和 SQLite3 作为外部框架而不是 Foundation 类存在的原因之一。

视图对象通常与 MVC 应用程序中的模型对象分离

这带来了使用该模式编程时的一个古老禁忌:让您的视图过于聪明。控制器在模型和视图之间提供了坚实的屏障,使得控制器充当模型层内容的导向器和过滤器。如果没有任何这样的障碍,比如 tableview,就必须确保每个单元格都有数据库中的数据副本,并且每个单元格都知道当更改在另一个单元格中传播时何时以及如何更新自己。在 Cocoa 中,这就是我们的NSWindowControllers进来。它们管理根视图的显示,并充当某些模型与其管理的视图内容之间的障碍。不过,重要的是要注意 Cocoa 中的控制器对象是视图偏向的,主要是因为如果没有大量不必要的胶水,几乎不可能为任何类型的模型层提供通用出口。

当模型对象发生变化时(例如,通过网络连接接收到新数据),它会通知控制器对象,控制器对象会更新相应的视图对象。

由于我在上面列出的原因,这就是应该的方式。但是,以您给出的网络示例为基础,考虑一下:给定一个获取数据的 NSOperation 和一个管理 tableview 的控制器,您可能不希望控制器将其胖手指伸入操作中,您也不喜欢tableview 接收 rawNSData并且必须花费宝贵的渲染时间来处理结果并显示它。

等等。那么,这是怎么回事?Cocoa 是否采用了自己的 MVC 理念,而不考虑常见的?还是我在查看 MVC 架构的常见方式中遗漏了一些东西?

我想我会从中得出的结论是,您对 MVC 中权力分离的定义以及 Cocoa 如何做到这一点是错误的。Cocoa 在坚持该模式方面相当严格,尽管在 Objective-C 社区中有一个有趣的当代运动朝着MVVM发展。

于 2013-05-29T06:51:01.210 回答
0

您是正确的,大多数可可应用程序中实践的 MVC 不是教科书中定义的 MVC。不同的框架采用了许多 MVC 变体。视觉设计师工具所使用的 MVC 很大程度上受其视觉设计师实现的影响。使用 XCode,您有故事板和笔尖。可可库和关注点的分离方式受此影响。如果您想利用这些工具,我建议您了解 Xcode 如何分离关注点并在此方法中工作。您的代码将与它更顺畅地共存。Apple 文档将对此有所帮助。

话虽如此,MVC 是关于关注点分离的。分离关注点在设计和维护软件中非常重要。适当地分离关注点可以减少依赖性,降低圈复杂性,并使您的代码更具可测试性和可维护性。我认为您关注这一点是很好的,无论您以何种方式构建 MVC,都应该将关注点分离的原因作为实施指南。

于 2014-09-12T14:17:38.853 回答