iOS VIPER架构,谁必须实例化整个模块?

考虑到VIPER结构

在这里输入图像说明

我有两个模块A和B.第一个模块A,通过演示者,想要执行一个必须在模块B中完成的动作,所以告诉它的线框去做。 问题是,谁负责实例化整个模块(视图,交互者,演示者…)。 我看到了一些不同方法的例子:

  • 在应用程序的开始创build所有模块。
  • 在模块的线框中创build整个模块,所以在这种情况下,BWireframe的一个类方法即时处理所有的B模块。

考虑到线框负责路由,是否也负责创build其模块?

TL; DR :我build议你应该使用像Typhoon这样的DI框架,并让它处理实例化。

您可能不希望线框实例化VIPER模块(View,Presenter,Interactor,DataManager)中的所有内容的原因是,您将直接为这些组件创build依赖关系。

依赖性使得软件不能改变:如果我们用洋葱结构 / 六边形结构的帽子来思考它,那么线框就会通过不仅知道视图而且还知道数据pipe理器,跨越至less两个独立的洋葱层的边界。

这迫使我们将线框视为通用的基础结构类:即应用程序最外层的东西。

然而,这与线框的其他(更真实的)责任相矛盾:做导航。 虽然这仍然是基础设施层,但它在UIKit-presentViewController:等等)中是-presentViewController:

所以恕我直言,VIPER的线框做得太多了。

唯一明智的做法是把这两项责任分开:

  1. VIPER类的初始化:可以引入一个工厂 ,或者使用专门解决这个问题的DI工具
  2. 做导航:这保持在一个Wireframe的职权范围内。

补充笔记

如果你想知道“ 谁来实例化下一个模块吗?”,那么恕我直言,我认为某些Module A的线框与Module B的线框对话是不正确的,尽pipeVIPER的post说了什么。

原因在于Module A现在将依赖于Module B ,导致紧密的耦合:这就损害了模块的目的。 在GitHub的VIPER-TODO项目上有关此主题的更多讨论=]

希望这可以帮助。

我认为模块的进入门是线框,所以我同意你的第二种方法。

创build一个模块包括创build它的所有对象,在我看来这是一种浪费。

  • 使用这个Xcode插件( https://github.com/natangr/ViperTemplate )自动创build并启动VIPER文件。

  • 阅读这篇文章,了解关于VIPER实例化的更多高级技巧(以及上述插件的解释): https : //www.ckl.io/blog/best-practices-viper-architecture/

自己的路由器上模块初始化代码将消除一堆代码重复,特别是对于大型项目。 您需要创build一次这些扩展名:

 // ReusableView.swift protocol ReusableView: class {} extension ReusableView { static var reuseIdentifier: String { return String(describing: self) } } // UIViewController.swift extension UIViewController: ReusableView { } // UIStoryboard.swift extension UIStoryboard { func instantiateViewController() -> T where T: ReusableView { return instantiateViewController(withIdentifier: T.reuseIdentifier) as! T } }