5

在使用 IB、NSObjectController 子类和绑定时,我一直在努力理解插入​​控制器逻辑的最佳方式。

我需要在模型和视图之间插入控制器逻辑,我正在努力寻找一种优雅的方式来做到这一点。是的,您可以向文件所有者发送操作并在其中处理控制器逻辑,但是当某些核心数据模型可以扩展到五十个或更多具有深度关系结构的实体时,这开始安装大量的样板代码。

一个非常简单的例子是这样的;假设您有一个具有四个字符串属性 myTextWinter、myTextSpring、myTextSummer、myTextAutumn 的实体。您有一个通过 NSObjectController 连接到 IB 中的视图。Now, say the user can select which 'Season' they wish to view by choosing Spring, Summer, Autumn, Winter from a Menu somewhere - when that season is selected, I would like to display the appropriate season's text.

在这个简化的示例中,我可能会在 NSDocument 子类中获取对象,创建一个我在视图中绑定到的名为 mySeasonText 的属性,然后检查我的 NSUserDefaults 是否有适当的季节,并将请求路由到模型中的适当属性.

当我有五十个实体时,问题就出现了,其中一些实体的关系有两个、三个或更深,每个实体都有自己的一组特定于季节的文本属性,我希望在从季节菜单中进行选择时在这些属性之间进行切换。或者,如果我有一堆 nsarraycontroller 链接在一起以访问更深层次的对象。

迄今为止,我一直在做以下事情;在我的每个模型对象中添加一个名为“mySeasonText”的属性,然后从我的控制器设置中获取设置,并路由到适当的季节。I refresh these objects whenever a new item in the menu is selected.

虽然这有效并消除了绝对大量的样板代码,但我的控制器逻辑现在在我的模型中。

一定会有更好的办法!有人可以指出我正确的方向吗?

4

1 回答 1

2

这是一个棘手的话题。苹果甚至在自己的文档中提到了这些挑战:

通过使用绑定技术,您可以轻松地创建一个 Cocoa MVC 应用程序,其视图直接观察模型对象以接收状态更改通知。然而,这种设计存在理论上的问题。视图对象和模型对象应该是应用程序中最可重用的对象。[...] 在设计方面,最好将模型和视图对象彼此分开,因为这样可以提高它们的可重用性。

您正在寻找的设计模式是中介控制器- 一种使用可可绑定类插入控制器逻辑的方法:

中介控制器通常是您从 Interface Builder 库中拖动的现成对象。您可以配置 [Mediating controllers] 以在视图对象的属性和控制器对象的属性之间建立绑定,然后在这些控制器属性和模型对象的特定属性之间建立绑定。因此,当用户更改视图对象中显示的值时,新值会自动传递给模型对象进行存储——通过中介控制器;当模型的一个属性改变它的值时,这个改变会被传递给一个视图来显示。

以下是我对他们的看法:你有没有看过电影或电视节目中两个角色需要交谈,但他们不会说任何相同的语言?他们找到其他人(或喜剧中的另外 5 个人),每个人都有一种共同语言,他们通过玩翻译电话的巨大游戏进行交流。

中介控制器有点像这样。

随着您的应用程序的增长,他们会了解所有关于在这个单一视图中查找这一事物的超级具体规则。这是应用程序需要运行的那种代码,但是当你把它放到你的模型中时,你理所当然地觉得它很讨厌。

对于几个具体和详细的​​示例,Apple 提供了这个非常详细的文档:Bindings Message Flow

有关此和相关 MVC + 绑定的一些非常好的讨论,请参阅:

于 2012-12-10T18:59:25.327 回答