为什么要组件化?
- 应用体积越来越大
- 业务代码耦合越来越多
- 代码量增加
- 不易于功能复用
组件化的优缺点
优点
- 业务分层、解耦,易于维护代码
- 便于各个业务功能拆分、抽离,实现真正的功能复用
- 业务隔离,利于跨团队开发代码控制和版本风险控制的实现
- 组件化对代码封装性、合理性都有一定的要求,提升开发人员的设计能力
缺点
- 增加开发人员的学习成本
- 增加了代码的冗余,组件化颗粒度越细,中间代码越多
- 增加了项目的复杂度
组件化方案有哪些?对应的优缺点?
-
Target-Action
: CTMediatorTarget-Action这个方案是基于
ObjC
的runtime
、category
特性动态获取模块,例如通过NSClassFromString
获取类并创建实例,通过performSelector
+NSInvocation
动态调用方法。首先每个模块需要配置Target和Category,其中Target是每个组件对应一个或者多个Target,Category是中间层Mediator的分类,使用分类的目的是为了让Mediator的业务代码分离,从而降低Mediator中的依赖和耦合性。
中间层Mediator利用了runtime的反射机制,在Category中找到对应Target以及对应的Action进行调用组件
优点
- 解耦,只存在组件依赖中间层(单向依赖)
- 利用 Category 可以明确声明的接口,进行编译检查
- 统一处理了所有组件间调用入口,方便管理
缺点
- 每个组件有对应的Category中间件,代码量增加
- 有硬编码问题,定义的String
-
URL Scheme
: JLRoutes、MGJRouterJLRoutes全局会保存一个Map,这个Map会以scheme为Key,JLRoutes为Value。所以在routeControllerMap里面每个scheme都是唯一的。
在每个JLRoutes里面都保存了一个数组,这个数组里面保存了每个路由规则JLRRouteDefinition里面会保存外部传进来的block闭包,pattern,和拆分之后的pattern。
优点
- 服务器可以动态控制页面跳转,可以统一处理页面问题之后的错误处理,可以统一三端(iOS、Android、H5)的请求方式
缺点
- URL短链接分布注册,导航的硬编码较多
- Class的load方法进行注册,太多对启动App时主线程有影响
- 内存常驻比较严重,所有的url、class、实例,block必须提前注册
-
Protocol
:BeeHive各个模块间从直接调用对应模块,变成以Service的形式,避免了直接依赖。App生命周期的分发,将耦合在AppDelegate中的逻辑拆分,每个模块以微应用的形式独立存在。
优点
- 协议接口规范,遵循依赖反转原则
- 无硬编码
缺点
- 缺少统一调度层,组件方法调用分散,难于集中管理
- 架构的灵活性不够高
项目中的组件化
架构的基础-五大原则
- 单一功能原则:对象功能要单一,不要在一个对象里面添加很多功能
- 开闭原则:扩展是开放的,修改是封闭的
- 里氏替换原则:子类对象是可以替代基类对象的
- 接口隔离原则:接口的用途要单一,不要在一个接口上根据不同入参实现多个功能
- 依赖反转原则:方法应该依赖抽象,不要依赖实例。iOS开发就是高层业务方法依赖于协议。
如何划分组件的上下层关系?
- 与业务无关的基础组件,比如网络请求、图片加载等
- 通用的功能组件,比如账号、统计埋点、支付、分享等
- 日常迭代的业务组件
组件设计严格执行五大原则进行设计。