在天猫App的快速发展过程当中,人员不断壮大,业务不断复杂,代码量随之增多,带来的是协做开发中遇到各类各样的问题。html
你是否曾在这样的环境下艰难开发?畏手畏脚地边作需求边改BUG。java
同时iOS的工程代码的耦合多是这样的:ios
AppDelegate中包含大量库的init以及其余操做,少则几百行,多则上千行,无关代码堆积在其中,维护成本极高,不一样库的调用逻辑互相交错,以下图所示:git
面条式的耦合,致使上层业务受限于底层基础库的依赖影响,BUG排查缓慢、新功能增长效率随代码量递增而不断递减。github
开发过程当中总结了如下App开发中遇到的问题:spring
一个App应该有以下特性:apache
开发人员但愿协同开发中可以作到如下几点:编程
代码隔离开发问题,经过Cocoapods获得解决,代码层面达到了分割,但逻辑功能上的耦合问题仍是没法解决。开发人员但愿在扩展业务的同时作到快速稳定,所以须要有一种App模块解耦方式来让开发人员中免受依赖关系的痛苦,因而让开发人员产生了打造一个BeeHive全局基础框架的想法。性能优化
BeeHive的使用方法能够参考BeeHive的README。这里举一个实际开发中的例子。bash
iPhone 6s及以上的设备支持3D-Touch后,几乎全部应用都在适配其特性,按照惯例,在AppDelegate中包含以下代码:
-(void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
{
....
}
复制代码
这意味着AppDelegate要增加代码行数,实则QuickAction的功能没有必要写在AppDelegate中。利用BeeHive框架特性,建立3DTouch Pod,独立3DTouch相关业务功能。
-(void)modQuickAction:(BHContext *)context
{
....
//process context.shortcutItem
}
复制代码
一个动态配置quickAction需求的到来,以往的作法须要引入配置Module,建立对应一系列调用流程,这时只须要调用配置Service便可,并且但愿更早的更新quickActionItem,因而能够调用modInit来实现。
-(void)modQuickAction:(BHContext *)context
{
....
//update config by configCenter Service
}
复制代码
产品方还但愿知道用户都用了哪些QuickAction,这时调用UserTrack Service便可,诸如此类的一个上层业务,开发人员要调用Log,Cache等等服务,采用BeeHive Service形式后只需一行调用便可。
在没有服务端的状况下,如何作到QuickAction个性化,注册并提供了3DTouchBHService,给其余业务调用好比某个功能页面
-(void)updateAccessTimesWithActionURL:(NSURL *)actionURL
{
....
// save view controller access times by cache service
// update local quickAction Items by access times and any other element
}
复制代码
上面三个典型场景主要涉及的到BeeHive几大功能点:
整个3DTouch开发过程当中不涉及其余其余功能的具体实现,面向切片编程过程当中,只要关心本身模块对应的需求便可。
BeeHive借鉴了Spring Service、Apache DSO的架构理念,采用AOP+扩展App生命周期API形式,将业务功能、基础功能模块以模块方式以解决大型应用中的复杂问题,并让模块之间以Service形式调用,将复杂问题切分,以AOP方式模块化服务,举例来讲日志、埋点模块采用AOP方式后,业务方不须要考虑日志、埋点的相关代码,只要以createService去声明调用Service便可。
相应的BeeHive架构以下:
Core + plugin的形式可让一个应用主流程部分获得集中管理,不一样模块以plugin形式存在,便于横向的扩展和移植。
图中的BHContext,是BeeHive的配置文件,提供全局统一上下文信息。
图中的BHCore即BeeHive提供注册、建立Module、Service逻辑,Module、Service注册和调用逻辑只和核心模块相关,Module之间没有直接的关联关系。
BeeHive核心思想涉及两个部分:
BeeHive提供了三种不一样的调用形式,静态plist,动态注册,annotation。Module、Service之间没有关联,每一个业务模块能够单独实现Module或者Service的功能。
图中包含了主要的BeeHive启动过程以及Module的时序逻辑。Module的事件分发源于BHAppDelegate中的triggerEvent,对应GlobalContext也在回调中提供给业务方。
BHAppDelegate中除了回调系统的事件,还将App生命周期进行扩展,增长ModuleSetup,ModuleInit,ModuleSplash,此外开发人员还能够自行扩展。
扩展周期过程当中,同时加入Module分析量化功能,每一个模块Init的耗时都可计算出来,为性能优化作到数据上的支持。一个App的业务增多过程当中,经过分析定位Module的Init耗时能够肯定须要优化的Module。
Module遵循BHModuleProtocol后,可以捕获App状态的回调,并拥有App生命周期内的全局上下文,经过context可获取配置参数,模块资源以及服务资源。
以BeeHive做为底层框架的App,除了解耦带来的便利,开发人员在开发新App过程当中涉及相同功能的Module,无需重复造轮子,直接移植Module,开发一个App如同拼装积木,能组合须要的功能业务。
上述图中包含Service相关的逻辑,业务A能够经过createService直接调用服务,Module根据需求动态注册某个服务。Service的调用和实现,核心是BHServiceManager。能够单首创建Services interface Pod,统一放置要用的Services,这样的业务依赖就从网状式变成中心式,业务方只需依赖Services一个。
Service能够动态共享对象,按需加载,BeeHive逻辑是将基础服务注册在plist中,业务型服务容许Service不先注册,直到业务须要时才被动态注册。
Service支持两种不一样模式:
在多线程环境下遇到了Service读写问题,已经过Lock来已避免Array crash问题。
不过Service还存在以下问题:
前者依赖问题计划经过调度机制来解决,后者还须要将AppDelegate更多业务剥离以及实践才可,这里不细谈。
BeeHive以一个分发App状态和统一Service Interface的架构形式解决了多团队多开发人员协同开发中的耦合问题。对于实践过程当中的开发成本,适应须要必定过程,但逻辑理顺后,应用起来不成问题。就收益而言,BeeHive更适合大型的多人项目以及快速移植的项目,小项目使用起来较复杂,有些得不偿失。
至此,BeeHive中主体已分析到位,BeeHive是一个正在成长的iOS框架,目前Star已1500+,但愿你们能够集思广益,多提issue、Pull Request,这样BeeHive也能让更多人受用。想象一下像蜜蜂同样优雅地搭建每一个蜂窝模块。
>做为一个开发者,有一个学习的氛围和一个交流圈子特别重要,这是个人交流群,你们有兴趣能够进群里一块儿交流学习761407670(123)
原文做者:戴鹏
地址:https://www.infoq.cn/article/beehive-a-ios-modular-decoupling-practice/