Coordinator 系列之初识 Coordinator 模式

翻译原文ios


视图控制器最大的问题之一是它们混合了您的导航逻辑、视图逻辑和业务逻辑。ui

当一个 tableViewCell 被选中时,代理方法一般会是这样的:spa

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {  
	id object = [self.dataSource objectAtIndexPath:indexPath];  
	SKDetailViewController *detailViewController = [[SKDetailViewController alloc] initWithDetailObject:object]  
	[self.navigationController presentViewController:detailViewController animated:YES];  
}
复制代码

三行简单的代码作了三件事:获取模型对象、建立视图控制器、展现视图控制器。在一个至关简单的 App 中,这样彻底没有问题。每一个视图控制器大几率只会使用一次。像这样耦合它们并非危险的操做。然而当你的App日益复杂,一个控制器可能会在一个新的地方被使用。也许会被适配到iPad上,也许在APP extension中,也许是一个老业务的新逻辑。

若是导航逻辑被写在了视图控制器中,那么这个控制器就无法不经过拖拽全部的代码来复用它已有的视图显示逻辑。不要忘记,视图控制器的基类是以UI为前缀,这说明它是视图对象,处理用户逻辑超出了它的能力范围。

在上面的代码中,视图控制器知道了如何建立整个业务流中的下一个对象以及如何显示它。在第三行代码中,它告诉它的父视图控制器要作什么,这显然是颠倒黑白的(译者:至关于儿子指挥老子作事情)。更糟糕的是,相似的代码分布在多个视图控制器中,每一个视图控制器只知道如何执行下一步。

我过去认为视图控制器是 App 中最上层的东西,是知道如何运行整个流程的东西。然而,最近我发现让一个更高级别的对象来指挥视图控制器有不少好处,这个对象的做用是引领和管理其权限内的全部视图控制器。

我把这些对象叫作 Coordinators,或者也能够叫作 Directors。要真正很好地执行此模式,您须要一个高级协调器来指导整个应用程序(有时称为应用程序控制器模式)。AppDelegate持有AppCoordinator,每一个协调器拥有一组子协调器。特别是若是你有不止一个控制器,如在标签栏应用,每一个导航控制器有本身的协调器,用于指导其行为和导航流。能够为注册或建立内容等特定任务建立更多的子协调器。每一个协调器由其父协调器建立。在开发过程的早期使用此模式,即便在单步任务(如身份验证)中也颇有用。

协调器是一个 PONSO(Plain Old NSObjects)纯粹的NSObject对象。对于 Instagram 的照片创做流程,咱们可使用PhotoCreationCoordinator。app协调器能够生成一个新视图,并将根视图控制器传递给它,这样它就能够在流中呈现第一个视图控制器。

- (void)beginPhotoCreationProcess {  
	PhotoCreationCoordinator *coordinator = [[PhotoCreationCoordinator alloc] initWithRootViewController:self.rootViewController delegate:self]  
	[self.childCoordinators addObject:coordinator];  
	[coordinator beginPhotoCreationProcess];  
}
	
- (void)photoCreationCompletedSuccessfully:(PhotoCreationCoordinator *)coordinator {  
	[self.childCoordinators removeObject:coordinator];  
}
	
- (void)photoCreationCanceled:(PhotoCreationCoordinator *)coordinator {  
	[self.childCoordinators removeObject:coordinator];  
}  
复制代码

协调器的-beginPhotoCreationProcess方法如今能够建立一个新的照片选择视图控制器,并根据须要配置它。协调器能够成为照片选择视图控制器的委托,以便它能够在显示下一步的时候获得通知。流程中的任何视图控制器都不须要知道任何其余视图控制器。每一个视图控制器都是一个孤岛。

业务逻辑(例如发布照片)被包装在属于其本身的对象中,能够根据须要向上挪到协调器或向下挪到模型。不管哪一种方式,它都从视图控制器移出去了。将其挪到协调器是很是好的,由于协调器已经充当代码不一样部分之间的粘合剂。

将流提取到协调器中有无数好处。视图控制器如今能够专一于将模型绑定到视图。能够更容易地重用它们,好比在扩展或非绑定应用程序中,而不须要复杂的条件来管理不一样的上下文。A/B 测试很是简单,只需建立一个不一样的协调器对象并使用它来启动流程。导航逻辑如今有了家,有家的感受真的很好。

视图控制器的初始化也被提取出来了。这一点不容忽视。初始化老是一个看起来简单实则更复杂的任务,须要大量关于类和配置的知识,咱们将它转移到一个更好的地方,在那里能够作出更明智的决定。

不知不觉协调器对象就会持有许多分离的状态,换句话说,特别是对于iPhone应用程序,随时都只能看到一个屏幕。这使它们水到渠成地成为使用状态机来管理其全部数据的合适场所。(译者注:状态机的最佳实现就是单向数据流,以后译者会引伸出来新的模式)。

苹果喜欢让视图控制器成为 iOS 世界的中心。这一点在 iOS 8 的新UISplitViewController api以及 storyboard segue等 Interface Builder 组件中很明显。不幸的是,以视图控制器为中心的应用程序开发方法是不可伸缩的。协调器是一种很好的方法,能够将代码隔离成小的、易于替换的块,成为解决视图控制器问题的解决方案的一部分。

相关文章
相关标签/搜索