一、背景
当我们的项目越来越复杂庞大,开发团队成员也不断增加,原先的项目架构在维护过程中效率越来越低,这时候需要提升开发效率,减少维护的成本,这时候就应该考虑重构项目,组件化开发是一个不错的选择。
二、组件化开发介绍
组件化开发,顾名思义,就是以组件的形式,按照业务功能等方式对我们现有的庞大的工程进行拆分,团队的不同成员负责各自的功能模块,且拆分出来的组件可以独立运行,互不干涉,最终将开发好的组件组合到宿主工程中的一套完整的解决方案。
组件化开发不仅仅是对项目进行重构,也给开发团队进行了划分,每个人的分工更加明确,对技术团队来讲也是一种重构。
组件化开发的优势
- 模块间解耦
- 提高模块的复用率
- 提升团队开发效率
- 方便单元测试
- 方便后期维护
组件化的实现思路
项目构建形式
每个组件以Pod库的形式存在,利用CocoaPods的方式安装各个组件,Git管理组件的版本,如下图所示:
iOS 组件化开发架构设计
组件化分层一:
组件化分层二:
注意点: 业务模块横向之间不能依赖,只能上层对下层依赖,项目公共代码资源下沉,横向的依赖也最好下沉。
关于解耦的一些优秀框架
CTMediator
CTMediator
利用runtime调用target-action的方式。在iOS中调用方法本质就是发送消息,消息包括 接受者 和 消息主体 。
在 iOS中可以直接调用某个对象的消息方式有两种:
一种是performSelector:withObject;
再一种就是NSInvocation。
第一种方式比较简单,能完成简单的调用。但是对于>2个的参数或者有返回值的处理,那performSelector:withObject就显得有点有心无力了,那么在这种情况下,我们就可以使用NSInvocation来进行这些相对复杂的操作。
CTMediator主要用的就是这两种方式: 部分代码摘录如下:
NSMethodSignature* methodSig = [target methodSignatureForSelector:action];
if(methodSig == nil) {
return nil;
}
const char* retType = [methodSig methodReturnType];
·····
if (strcmp(retType, @encode(NSUInteger)) == 0) {
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
[invocation setArgument:¶ms atIndex:2];
[invocation setSelector:action];
[invocation setTarget:target];
[invocation invoke];
NSUInteger result = 0;
[invocation getReturnValue:&result];
return @(result);
}
return [target performSelector:action withObject:params];
MLSOAppDelegate
MLSOAppDelegate : 通过runtime的事件转发,将代理协议中的方法进行动态转发,在自己代码中没有实现所有代理方法。
FRDModuleManager
FRDModuleManager : 实现代理中所有方法,简单的将AppDelegate的单路代理改成多路代理。
BeeHive
BeeHive:
用于iOS应用开发的App模块化编程的框架实现方案,吸收了Spring框架Service的理念来实现模块间的API耦合,就是一个中间层。
三、组件化开发的解决方案
网友的解决方案一:
基于 MLSOAppDelegate 进行优化,增加 BeeHive 的优点(支持顺序设定、异步加载),支持相对顺序+CTMediator进行优化(增加Target预检测),业务层增加部分抽象。
四、组件化实践
Cocoapods 介绍
1、利用pod命令创建模块
pod lib create xxxModule
在终端输入该命令之后,会出现一些提示需要填写的内容,按照自己的需求填写,然后回车就可以了。 最终在本地生成一个文件夹,目录大概如下所示(以上过程都是pod帮我们完成的):
2、编写模块
我们编写代码的地方就在Classes文件夹下面。
3、安装并使用模块
等编写完成之后,进入如图所示Example目录,执行pod install
可以看到编写的Module已经被添加到了该Example的Pods目录下.
4、组件的第三方和本地依赖处理
当我们编写组件的时候,不可避免地要引用到一些第三方的组件,那么怎么解决三方组件的依赖问题呢?
如下是三方依赖添加的位置:
本地组件依赖的添加在Podfile中添加,指定路径,如下图所示:
5、组件化资源文件的加载问题
当我们把上述工作准备好,运行的时候会发现资源文件未加载出来,那接下来就解决该问题:
先将图片资源放到Module目录下的Assets文件夹下面,接下来资源加载的方式也需要修改一下:
还需要修改如下所示的文件:
回到刚刚的工程下,重新执行pod install,然后就可以加载出来了。