许多面孔的VIPER-第2部分:iOS演示

……从第1部分开始,我们解释了动机,现在我们将介绍该演示项目。

为了使您能够以最快的方式轻松理解此演示代码库,我将首先为以下操作提供一个简单的序列图:

  • 仪表板是第一次加载
  • 用户点击任何重要亮点
  • 用户从上次付款列表中选择付款

这些动作将通过3个视图控制器的序列图进行介绍:

DashboardViewController

这基本上是我们的主要观点

LastPaymentsViewController和PaymentDetailViewController

LastPaymentsViewController嵌入到DashboardViewController. 并从中显示PaymentsDetailViewController

这两个图显示了以下操作顺序:

  • 调用DashboardViewController viewDidLoad()方法后,然后配置Highlights上的target-action
  • 调用模拟的API,该API将TopHighlight对象返回给DashboardViewController ,该DashboardViewController使用TopHighlightsSectionViewModel返回对DashboardViewController的调用,该调用基本上包含展开/折叠的表示模式和TopHighlightViewModel对象数组
  • DashboardViewController调用其子视图Highlights并将其传递给TopHighlightsSectionViewModel ,后者使用它填充视图
  • 还调用了LastPaymentsViewController viewDidLoad()方法,因为后者是DashboardViewController的子视图
  • Top Highlights类似,我们调用API并填充UITableView
  • 点按任何“ 顶部亮点”将折叠或展开“顶部亮点”视图
  • 点击任何付款单元将导航到PaymentDetailViewController

为了用上面的简短描述补充序列图,我将跳过此简短代码示例的链接,这里无需单独解释各部分。

您将看到,它使用了面向模块的体系结构概念,这不是本文的重点。

类结构不是刚性的

我们已经在第1部分中对此进行了描述,但是可以在这里重申它。 我们在使用业务逻辑,服务层和视图方面一直非常务实,但我们并未牺牲质量,并提供了很高的测试覆盖率。 请记住,我们在这里只谈论仪表板 模块的覆盖范围……在其他地方,有很多样板未经测试。

样板代码

我们可以看到,由于面向模块的体系结构和协议扩展的使用,我们将样板减少到最低限度:

  • 线框减少到最小实例化变量
  • 演示者实现ModuleRoutable协议的3个迷你功能
  • 模块类还包含4个变量。

几乎没有任何样板代码…而且,根本不需要添加太多代码即可使核心VIPER类正常运行,从而大大减少了时间并缩短了学习时间。 这也为原型和小型项目提供了理想的基础,几乎提供了一种可以帮助您完成工作的框架商品。

苹果MVC和Storyboard的无缝集成

对于已经阅读了面向模块的体系结构系列,尤其是第6部分-使MVC脱颖而出的人们,您已经了解了如何轻松地将业务流与UI导航元素集成,而又没有他们接管我们的体系结构和应用程序流。

类之间的复杂沟通

我认为从内存管理的角度来看,我们也已经以一种干净安全的方式处理了这一问题,这又得益于面向模块的架构,VIPER和基本的OOP原理。 为了证实这一点,我将再次使用第1部分中的类模式:

  • View Controller 单方面Presenter通信并拥有它
  • 演示者线框也是如此
  • 线框创建视图控制器,并将其分配给应用程序的视图/导航堆栈
  • 模型对象绝不会以任何其他方式持久化或变为有状态
  • Presenter是唯一拥有View模型的人
  • 查看对象未引用类中的任何其他对象
  • 模块不拥有任何类,它仅充当创建Presenter的网关,后者通过Wireframe创建View Controller时 ,就被分配给它,并且脱离了模型的功能范围/循环,并且没有与之连接从外面
  • 一旦结构形成,我们可以看到整个图只有一个所有者,基本上就是UIWindow ,例如,一旦用户点击“后退”按钮, View Controller就被释放,整体结构。 没办法,我们会招致大规模内存泄漏

可能出什么问题了?

一些事情。 有人会认为Presenter在理想情况下不应该具有状态。 尽管我认为这有点过分自信,但我同意如果不是Dashboard,而是某些服务模块,我们至少必须同步对属性的访问。 尽管如此,使其PaymentDetailViewController无状态将要么创建另一个用于填充PaymentDetailViewController API调用,要么一次性创建后者并将其保留在其他位置,这将是一个非常肮脏的解决方案……

而且,如果视图更复杂,则对象之间的关系会更多,并且Presenter可能会成为一个繁忙的结点,任务过多且耦合过多,这将是更一般的情况。

但这就是我们接下来将要解决的问题,事情将变得更加复杂……

我们的演示项目处于第一个阶段,它与第1部分中设定的期望完全吻合,我们需要查看它是否能够经受住复杂性的考验。 但是,如前所述,这是第3部分的内容……

敬请关注。