最佳实践:重构 AppDelegate(iOS)

栏目: IOS · 发布时间: 5年前

内容简介:引言:可能很多读者可能都有这样的经历,迭代维护多年的系统代码量激增,有些模块的代码自己都觉得丑陋,可是却不敢重构,生怕一不小心被拉取祭天,然后来了个愣头青实习生正好参与这个模块迭代,一顿骚操作后这个模块炸了,那么面对屎山一样焦灼耦合的代码,面对产品汪随着手机壳颜色变化APP主题这种变态需求的时候,如何不在这坨屎山里修修补补,如何重构屎山,让你的代码成为金字塔一样的艺术品?

【后台回复“ 1024 ”,送你一个特别推送】

最佳实践:重构 AppDelegate(iOS)

引言:可能很多读者可能都有这样的经历,迭代维护多年的系统代码量激增,有些模块的代码自己都觉得丑陋,可是却不敢重构,生怕一不小心被拉取祭天,然后来了个愣头青实习生正好参与这个模块迭代,一顿骚操作后这个模块炸了,那么面对屎山一样焦灼耦合的代码,面对产品汪随着手机壳颜色变化APP主题这种变态需求的时候,如何不在这坨屎山里修修补补,如何重构屎山,让你的代码成为金字塔一样的艺术品?

老峰最近读了V8tr写的Refactoring Massive App Delegate感觉写的挺好,就翻译过来分享给大家,正好以AppDelegate重构来讨论下如何重构复杂业务代码。

AppDelegate连接应用程序和系统,通常被认为是每个iOS项目的核心。随着开发的迭代升级,不断增加新的功能和职责,它的代码量也不断增长,最终导致了Massive AppDelegate(臃肿的AppDelegate)。

在复杂App Delegate里修改任何东西的成本都是很高的,因为它将会影响你的整个APP,一不留神就吃bug 。毫无疑问,保持AppDelegate的简洁和清晰对于健康的iOS架构来说是至关重要的。本文我们将使用多种方法来重构,使之简洁、可重用和可测试。

Massive AppDelegate 的问题

AppDelegate是应用程序的根对象。它确保应用程序与系统以及其他应用程序正确的交互。AppDelegate理通常会承担很多职责,这使得很难进行更改,扩展和测试。

通过调研几十个最受欢迎的开源iOS应用程序,我把AppDelegate常见的业务代码列出如下。我相信我的读者也写过这样的代码,或者维护或者支持这种类似混乱的项目。

  • 初始化许多第三方库(如分享,日志,第三方登陆,支付)

  • 初始化数据存储系统

  • 管理UserDefaults:设置首先启动标志,保存和加载数据

  • 管理通知:请求权限,存储令牌,处理自定义操作,将通知传播到应用程序的其余部分

  • 配置UIAppearance

  • 管理App Badge Counter

  • 管理后台任务

  • 管理UI堆栈配置:选择初始视图控制器,执行根视图控制器转换

  • 日志埋点统计数据分析

  • 管理设备方向

  • 更新位置信息

这些臃肿的代码是反模式的,像屎一样难于维护。显然支持扩展和测试这样的类非常复杂且容易出错。例如,查看Telegram的AppDelegate的源代码会激起我的恐惧。Massive App Delegates与我们经常谈的Massive View Controller的症状非常类似。

在我们同意Massive App Delegate的问题存在并且非常重要之后,让我们看看可能的解决方案,每个Recipe(方案)遵循单一职责、易于扩展、易于测试原则。下面列出Recipes。

Recipe #1:(Command Design Pattern)命令模式

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。因此命令的调用者无需关心命令做了什么以及响应者是谁。

可以为APPdelegate的每一个职责定义一个命令,这个命令的名字有他们自己指定

最佳实践:重构 AppDelegate(iOS)

然后我们定义StartupCommandsBuilder来封装如何创建命令的详细信息。APPdelegate调用这个builder去初始化命令并执行这些命令

最佳实践:重构 AppDelegate(iOS)

最后只需在didFinishLaunchingWithOptions中初始化就可以了

最佳实践:重构 AppDelegate(iOS)

如果APPdelegate需要添加新的职责,则可以创建新的命令,然后把命令添加到Builder里去而无需去改变AppDelegate。解决方案满足单一职责、易于扩展、易于测试原则。

Recipe #2: Composite Design Pattern 组合 设计模式 组合模式

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。一个很明显的例子就是iOS里的UIView以及它的subviews。

这个想法主要是有一个组装类和叶子类,每个叶子类负责一个职责,而组装类负责调用所有叶子类的方法。

最佳实践:重构 AppDelegate(iOS)

接下来,实现执行具体职责的叶子类

最佳实践:重构 AppDelegate(iOS)

我们定义AppDelegateFactory来封装创建的逻辑,在AppDelegate通过工厂方法创建组装类,然后通过他去调用所有的方法

最佳实践:重构 AppDelegate(iOS)

他满足我们在开始时提出的所有要求,如果要添加一个新的功能,很容易添加一个叶子类,无需改变AppDelegate,解决方案满足单一职责、易于扩展、易于测试原则。

Recipe #3: Mediator Design Pattern 中介者模式

中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。

如果您想了解有关此模式的更多信息,我建议您查看Mediator Pattern Case Study。或者阅读文末老峰也给出关于设计模式比较经典的书籍。

让我们定义AppLifecycleMediator将UIApplication的生命周期通知底下的监听者,这些监听者必须遵循AppLifecycleListener协议,如果需要监听者要能扩展新的方法。

最佳实践:重构 AppDelegate(iOS)

定义AppLifecycleListener协议,以及协议的的实现者

最佳实践:重构 AppDelegate(iOS)

我们定义好静太实例方法,初始化所有监听者

最佳实践:重构 AppDelegate(iOS)

现在它只需要1行代码就能加入到AppDelegate中

最佳实践:重构 AppDelegate(iOS)

这个中介者自动订阅了所有的事件。AppDelegate仅仅需要初始化它一次,就能让他正常工作。每个监听者都有一个单一职责,很容易添加一个监听者,而无需改变Appdelgate的内容,每个监听者以及中介者能够容易的被单独测试。

总结

我们认为大多数AppDelegates的设计都不太合理,过于复杂并且职责过多。我们称这样的类为Massive App Delegates。

通过应用软件设计模式,Massive App Delegate可以分成几个单独的类,每个类都有单一的责任,可以单独测试。

其实本文中的解耦方法并不局限于在App Delegate中使用,我们的UIViewController也可以采用设计模式去优化去解耦,本文源码见文末。

这样的代码很容易更改维护,因为它不会在您的应用程序中产生一连串的更改。它非常灵活,可以在将来提取和重用。

推荐阅读:

  1. https://www.vadimbulavin.com/refactoring-massive-app-delegate/

  2. https://github.com/GesanTung/RefactoringMassiveAppDelegate

  3. OC设计模式:《Objective-C编程之道:IOS设计模式解析》

  4. Swift设计模式: Design_Patterns_by_Tutorials_v0.9.1

  5. 重构:《重构改善既有代码的设计》

PS:公号后台回复关键词【设计模式 】可获得电子版

最佳实践:重构 AppDelegate(iOS)

更多骚操作,尽在iOSTips,关注公众号,第一时间get新姿势


以上所述就是小编给大家介绍的《最佳实践:重构 AppDelegate(iOS)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Release It!

Release It!

Michael T. Nygard / Pragmatic Bookshelf / 2007-03-30 / USD 34.95

“Feature complete” is not the same as “production ready.” Whether it’s in Java, .NET, or Ruby on Rails, getting your application ready to ship is only half the battle. Did you design your system to......一起来看看 《Release It!》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具