内容简介:引言:可能很多读者可能都有这样的经历,迭代维护多年的系统代码量激增,有些模块的代码自己都觉得丑陋,可是却不敢重构,生怕一不小心被拉取祭天,然后来了个愣头青实习生正好参与这个模块迭代,一顿骚操作后这个模块炸了,那么面对屎山一样焦灼耦合的代码,面对产品汪随着手机壳颜色变化APP主题这种变态需求的时候,如何不在这坨屎山里修修补补,如何重构屎山,让你的代码成为金字塔一样的艺术品?
【后台回复“ 1024 ”,送你一个特别推送】
引言:可能很多读者可能都有这样的经历,迭代维护多年的系统代码量激增,有些模块的代码自己都觉得丑陋,可是却不敢重构,生怕一不小心被拉取祭天,然后来了个愣头青实习生正好参与这个模块迭代,一顿骚操作后这个模块炸了,那么面对屎山一样焦灼耦合的代码,面对产品汪随着手机壳颜色变化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的每一个职责定义一个命令,这个命令的名字有他们自己指定
然后我们定义StartupCommandsBuilder来封装如何创建命令的详细信息。APPdelegate调用这个builder去初始化命令并执行这些命令
最后只需在didFinishLaunchingWithOptions中初始化就可以了
如果APPdelegate需要添加新的职责,则可以创建新的命令,然后把命令添加到Builder里去而无需去改变AppDelegate。解决方案满足单一职责、易于扩展、易于测试原则。
Recipe #2: Composite Design Pattern 组合 设计模式 组合模式
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。一个很明显的例子就是iOS里的UIView以及它的subviews。
这个想法主要是有一个组装类和叶子类,每个叶子类负责一个职责,而组装类负责调用所有叶子类的方法。
接下来,实现执行具体职责的叶子类
我们定义AppDelegateFactory来封装创建的逻辑,在AppDelegate通过工厂方法创建组装类,然后通过他去调用所有的方法
他满足我们在开始时提出的所有要求,如果要添加一个新的功能,很容易添加一个叶子类,无需改变AppDelegate,解决方案满足单一职责、易于扩展、易于测试原则。
Recipe #3: Mediator Design Pattern 中介者模式
中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。
如果您想了解有关此模式的更多信息,我建议您查看Mediator Pattern Case Study。或者阅读文末老峰也给出关于设计模式比较经典的书籍。
让我们定义AppLifecycleMediator将UIApplication的生命周期通知底下的监听者,这些监听者必须遵循AppLifecycleListener协议,如果需要监听者要能扩展新的方法。
定义AppLifecycleListener协议,以及协议的的实现者
我们定义好静太实例方法,初始化所有监听者
现在它只需要1行代码就能加入到AppDelegate中
这个中介者自动订阅了所有的事件。AppDelegate仅仅需要初始化它一次,就能让他正常工作。每个监听者都有一个单一职责,很容易添加一个监听者,而无需改变Appdelgate的内容,每个监听者以及中介者能够容易的被单独测试。
总结
我们认为大多数AppDelegates的设计都不太合理,过于复杂并且职责过多。我们称这样的类为Massive App Delegates。
通过应用软件设计模式,Massive App Delegate可以分成几个单独的类,每个类都有单一的责任,可以单独测试。
其实本文中的解耦方法并不局限于在App Delegate中使用,我们的UIViewController也可以采用设计模式去优化去解耦,本文源码见文末。
这样的代码很容易更改维护,因为它不会在您的应用程序中产生一连串的更改。它非常灵活,可以在将来提取和重用。
推荐阅读:
-
https://www.vadimbulavin.com/refactoring-massive-app-delegate/
-
https://github.com/GesanTung/RefactoringMassiveAppDelegate
-
OC设计模式:《Objective-C编程之道:IOS设计模式解析》
-
Swift设计模式: 《 Design_Patterns_by_Tutorials_v0.9.1 》
-
重构:《重构改善既有代码的设计》
PS:公号后台回复关键词【设计模式 】可获得电子版
更多骚操作,尽在iOSTips,关注公众号,第一时间get新姿势
以上所述就是小编给大家介绍的《最佳实践:重构 AppDelegate(iOS)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 最佳实践:重构AppDelegate
- iOS重构实践
- iOS重构之面向协议编程实践
- Go 工程化(九):项目重构实践
- “流量回放” 在系统重构中的测试实践
- 重构实践:基于腾讯云 Elasticsearch 搭建 QQ 邮箱全文检索
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。