组件化开发 (序)

组件化现在在业内可谓是如火如荼,无论是面试 还是吹逼,你要是说没整过组件化,你都不好意思给人打招呼。正好公司项目在技改阶段,我们就趁此机会也搞一搞组件化开发。

1.为什么要组件化?

先来解释一下:什么是组件化? 
   1.组件:一般我们用于命名比较小的功能块,如:下拉刷新 提示框组件等。而较大粒度的业务功能,我们习惯称之为”模块”,如:搜索,购物车,登陆模块等
   2.组件化:也可称为模块化。每个组件完成特定的功能,然后组件间像搭积木的方式组合在一起,形成一个整体。这就是组件化。 
   总结来说就是:组件化就是把APP拆分成一个个组件,组件之间相对独立,然后通过主工程将项目所需要的组件组合起来。组件化后的项目就变成了很多小模块,其他项目中有类似的需求,都可以像导入第三方库似的导入组件,进行快速开发,方便维护。
复制代码

组件化的优点:

  1. 解决人多(更好的协作)、业务线多、需求多(更好的功能模块划分)的问题
  2. 解决项目模块间的代码耦合问题
  3. 代码的可读性,复用性,代码质量,提升逼格
  4. 实现真正的功能复用,比如同样的功能模块如果实现了自完备性,可以在多个app中复用
  5. 业务隔离,跨团队开发代码控制和版本风险控制的实现
  6. 组件化对代码的封装性、合理性都有一定的要求,提升开发同学的设计能力
  7. 减少编译时间,因为组件倒入已经变成二进制,提升编译速度
  8. 对于调试工作,应该放在每个组件中完成。单独的业务组件可以直接提交给测试提测。最后组件开发完成并测试通 过后,再将所有组件更新到主项目,提交给测试进行集成测试即可

缺点也有,比如:

  1. 组件化时间成本高,对项目熟悉度要求高,组件化选择方案很重要
  2. 入门门槛较高,新手入门需要的成本也更高,但是 又反向要求了维护项目发展 对人员水平也有促进提高作用
  3. 因为组件间要接耦,这就不可避免的会使组件内部增加了很多重复代码
  4. 需要有专人维护。工具的使用成本 团队间和模块间的配合成本升高,开发效率短期会降低
    但是从长期的影响来说,带来的好处远远大于坏处的,因此组件化仍然是最佳的架构选择

2.组件化的内容

组件化其实总结起来就是两部分:

· 公共服务(包括基础服务,业务组件)
· 中间件

复制代码

把握好划分粒度的细化程度,太细则项目过于分散,太大则项目组件臃肿。但是项目都是从小到大的一个发展过程,所以不断进行重构是掌握这个组件的细化程度最好的方式。

模块解耦的目标就是, 在基于模块设计原则上, 让模块之间没有循环依赖, 让业务模块之间解除依赖。

使用组件化架构开发,组件间的通信都是有成本的。所以尽量将业务封装在组件内部,对外只提供简单的接口。**即“高内聚、低耦合”**原则。

公共服务:下沉到底部,业务方不用关心这些,造轮子交给底层架构者.

公共服务分为:基础组件,业务组件

基础组件是下沉到底部的,作为公共基础的组件,它可以被业务组件依赖,但不可依赖业务组件,而且业务组件之间不可耦合。

针对基础组件要做的是

抽离公共基础组件(跨产品使用,给业务没有关系,给哪个app 哪个公司没有关系),比如:网络,log日志,第三方SDK管理,地图服务,社会化分享 登陆 统计,文件服务,category。 抽离成私有pod。

抽离产品基础库(给微脉强相关的),比如:通用UIBase,自定义HUD,图片选择 浏览器,用户行为统计库,应用基本配置,及其他自定义的UI基础组件。以及管理器Manager , 项目里用的次数多的基础组件,不需要拆的小功能组件等,都是基础组件, 抽离成私有pod。

业务组件是一个个独立的业务模块,比如登陆模块,搜索模块,设置模块等,这些业务模块是可以单独拿出来作为一个项目进行开发测试的,由相应业务线的人来做,与其他业务不关联,减少耦合,易于开发维护修改定位重构,每个业务模块都有相应负责人管理负责,减少代码冲突,增加开发效率。

而最后的理想结果就是,大项目就是个壳工程。

壳工程: 每个业务都是组件,大工程只是个壳,搭积木的方式完成整个工程。

中间件:就是管理组件之间的通信。

组件分离完成后,该考虑的就是组件之间怎么通信了。






在不使用中间层的情况下,各个组件之间都是直接依赖,就是组件直接#import被调用的组件,这些依赖关系凌乱而且复杂,在这种依赖关系下,如果想要多个组件并行开发,必须跟其他组件开发者做好接口约定,这里可能会有一份组件的接口文档,当组件接口出现变动时,需要通知所有此组件的使用者修改调用方法,这种情况下,后期维护会非常困难。

在使用中间层之后,所有的依赖关系都转接到中间层上了,所有的组件间通信都在中间层上集中处理,这样当组件出现变化时,只需要修改中间层就可以了。

**中间层的作用是:**帮助不同组件进行通信,它不可避免的会对组件形成依赖。虽然可以通过一些手段使得中间层与组件在编译层面上解耦了,但是中间层和组件仍然会存在业务上的关联。 换句话说,当使用中间层隔离各个组件时,中间层必然会与业务存在关联。

如果想要复用中间层,则必须将具体的业务逻辑剥离出中间层。在本文中,将剥离了具体业务的中间层称作中间件通用工具,RouterMediator都是这种工具,

看了些技术博客,比较了router和mediator,还是mediator设计的更合适些,通过中间件Mediator 进行调度,runtime进行内部解耦,组件仅通过Action暴露可调用接口,调用方调用时传入相应的target和param。组件之间完全没有依赖。

我们项目选用的就是mediator。

3.组件化的注意点

总结了一些在进行组件化开发时需要注意的地方:

  • 组件的拆分粒度:组件拆多细? 拆到哪一层级合适? 根据每个app情况 具体开发中不断完善。
  • 不同组件中资源重复:每个组件管理自己的资源,不能依赖其他资源,就算重复拷贝也没事。
  • OC和Swift混编问题: 组件里 不能用Swift开发,不然会在编译时报错!
  • 组件里少用或不用宏: 预防组件间 或工程里,宏定义名字一样,编译错误。
  • 组件里不允许出现common组件:单个组件一定要求分工明确,功能单一。
  • 按照架构的层数从上到下依赖,不要出现下层模块依赖上层模块的现象。
  • 越底层的模块,应该越稳定,越抽象,越具有高复用度。。
  • 回调尽量用block(注意循环引用),少用delegate(减少耦合 依赖 )

微脉的组件化

现状和需求:



理想情况:

网络请求,网络监测,持久化,分享,统计,支付,推送,定位,图片选择器,pickerView,HUD,alert框,actionSheet框,3Dtouch,手势,自定义刷新加载,小功能通用组件,categary,购物车,搜索等,全部做成私有库 发布到公司gitlab。 大工程直接pod就行了。 组件要是升级,大工程update,做好版本控制。 其他app也都可以pod使用。 哪个模块出问题,找到相应组件 进行修复,迅速定位。 必须有专人维护组件,组件功能不完善时或发现问题时,须通知到专人,让其修改,杜绝其他人修改,避免混乱。

现实情况:

因为项目历时四年,很多业务的变更,盘子太大,不是所有人对整个项目都很熟悉,也不是每条业务线都有时间,所以暂时业务线这块我从 “我的” 模块开始着手。竹叶从挂号医院那块开始。

先把里面跳转的 用 Meditor 调度,

先把给业务无关的基础服务组件 剥离出来,放到common文件(是否传到私有库 看大家意见,不过没有私有库,组件化没多大意义)

我先把图片选择组件写好,然后创建私有库传上去。

代码规范: 一般通用的OC代码规范就行,写代码多注意,另项目类和组件前都统一加WM。