MVC设计 - 维护视图控制器中模型对象的持久引用

时间:2013-12-03 15:02:34

标签: ios objective-c oop

在设计iOS应用程序时,我始终遵循模型 - 视图 - 控制器(MVC)模式,并设计视图控制器类以在必要时引用模型中的类,并仅在性能或数据持久性受到关注时保留指针。其中一个原因是,只有在需要强依赖性时,才能通过实现对象之间的关系来限制瞬态依赖性。

我正在设计一个应用程序,其场景每个都包含一个带有一个或多个从属视图和视图控制器的根视图控制器。这让我想到应该如何维护至少一些模型对象的指针。

我考虑过的一个替代方案是,只有在需要时才能让视图控制器访问模型,但是对于模型中的类在场景中的多个视图控制器之间共享的情况,将它们锚定在场景的根视图控制器中。这样做的好处是,它简化了模型对象生命周期的内部管理,避免了单例,但是它在从属视图控制器和根视图控制器之间增加了依赖关系。需要引用这些模型对象的视图控制器才能通过根视图控制器获取引用。

我正在寻求别人的建议和意见,以了解我可能没有想过的这类设计中可能存在的陷阱。在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

在设计接口时,请记住最小化对象依赖项的数量和持续时间是一个很好的原则。这应该可以帮助您限制每个对象的职责,并使它们更容易测试,并在需要时重构为更小的组件。

避免单例还支持结构良好的对象集(单个实例当然是许多应用程序的现实,但这并不意味着需要使用Singleton模式强制执行或访问它们)。避免单例有助于避免类和全局状态之间隐藏的紧密耦合,这两者都会导致难以测试,理解和重用的类。

  

con是它在从属视图控制器和根视图控制器之间添加依赖关系。需要引用这些模型对象的视图控制器才能通过根视图控制器获取引用。

我认为,这忽略了设计MVC应用程序时常用的一个重要原则。对象应该将它们的依赖关系传递给它们,它们不应该伸出来获取引用。

如果子对象从其父对象请求依赖关系,那么您已将这些对象耦合在一起。如果您通过“数据源”委托之类的接口这样做而不是对parentViewController属性的类进行假设,则这不一定是不合理的。传递数据源,工厂或服务对象(如CoreData托管对象上下文)都是合理的依赖关系,可以代替特定的模型实例提供给对象。

让您的根控制器构建其下属,并将模型(或数据源或其他代理到这些模型)传递给这些下属。然后,每个从属视图控制器都不依赖于被呈现为特定父级的子级,并且可以更容易地在另一个上下文中重用。

在某些情况下,这可能意味着那些视图控制器保留了他们整个生命中需要显示的模型,但我发现这通常不是问题。如果价格昂贵,那么通常很容易重构控制器以依赖工厂或服务,工厂或服务可以按需生成模型,而不是直接依赖于模型的实例。

这种方法可以允许您使用基于构造函数的依赖注入(将所有对象的依赖项传递给它的构造函数[obj-c中的init方法],而不是通过属性设置它们)。这样做可以强制您只能创建一个实例,其中包含所有必需的依赖项,这有助于避免混淆(而不是希望它们在需要之前设置为属性或处理更改这些属性的后果它们正在使用中)。这在obj-c中并不总是有意义的,你可能有几种方法来构造一个对象(例如init vs awakeFromNib),但它是一个选项。

当这种方法导致对象接受许多依赖关系只是为了将它们传递给子对象时,可能会考虑依赖注入框架(如注释中建议的@Kirualex)来管理可以通过其获取依赖关系的中心位置。