-
url注册对于实施组件化是完全没有必要的,拓展性和可维护性都降低;
-
基于openURL的方案的话,有一个致命缺陷:非常规对象无法参与本地组件间调度;但是可以通过传递params来解决,但是这样区分了远程调用和本地调用的入口;
-
模块内部是否仍然需要使用URL去完成调度?是没有必要的,为啥要复杂化?
反革命的组件化方案:
基于Mediator模式和Target-Action模式:
[CTMediator sharedInstance]
openUrl:url] //call from other app with url
parseUrl
performTarget:action:params //call form Native Module
runtime
[TargetA action1], [TargetA action2]
[TargetB action1], [TargetB action2]
反革命组件化方案的调用方式:
本地跨组件间调用:
[[CTMediator sharedInstance] performTarget:targetName action:actionName params:@{…}]
远程应用调用:
openUrl + parseUrl的方式; 针对请求的路由操作,直接将Target和Action的名字封装到url中;
反革命组件化方案的好处:
-
将远程调用和本地调用做了拆分,而且由本地应用调用位远程应用调用提供服务;
-
组件仅通过Action暴露可调用接口;
-
组件化方案必需去Model设计:只有调用方依赖Mediator,响应方依赖是没有必要的;
-
调用方如何知道接收方需要哪些Key的参数,如何知道有哪些target可被调用?:在mediator中维护针对Mediator的Category,每个category对应一个target,categroy中的方法对应Action场景;
-
category为组合模式,根据不同的分类提供不同的方法,每个组件对应一个category分类;
-
参数验证和补救入口;
-
轻松的请求转发;
-
统一了所有组件间调用入口;
-
param的hardcode在整个app的作用域仅仅存在于category中,跟调用宏差不多;
-
安全保证,对url中进行native前缀验证;
-
保证动态调度考虑;
反革命组件化方案开源Demo:
代码Git地址:https://github.com/casatwy/CTMediator.git
二、实际项目中的组件化问题
(1) 为什么要组件化?
-
解决人多(更好的协作)、需求多(更好的功能模块划分)的问题;
-
解决项目模块间的代码耦合问题;(坚决抵制业务组件间代码直接引用)
(2)如何拆分组件?(神仙们讨论的主要是产品业务组件化的问题)
-
基础功能组件:(类似于性能统计、Networking、Patch、网络诊断等)
-
按功能分库,不涉及产品业务需求,跟库Library类似
-
通过良好的接口拱上层业务组件调用;
-
不写入产品定制逻辑,通过扩展接口完成定制;
-
基础UI组件:(例如下拉刷新组件、iCausel类似的组件)
-
产品内通用UI组件;(各个业务模块依赖使用,但需要保持好定制扩展的设计)
-
公共通用UI组件;(不涉及具体产品的视觉设计, 目前较少)
-
产品业务组件:(例如圈子、1元购、登录、客服MM等)
-
业务功能间相对独立,相互间没有Model共享的依赖;
-
业务之间的页面调用只能通过UIBus进行跳转;
-
业务之间的逻辑Action调用只能通过服务提供;
(3)组件化工程需要解决的问题?
-
组件化页面跳转(UIBus)方案要求:
-
能够传递普通参数(系统基础数据类型)和复杂参数(url无法负载的对象),不负责CustomModel的传递处理;
-
能够获取url对应的controller进行TabController的动态配置;
-
能够对controller的present方式进行定制;
-
url的注册须用代码完成,必需去中心化处理;
-
组件服务化(ServiceBus)方案要求:
-
能够传递普通参数和复杂参数,尽量不使用CustomModel的传递;
-
通过接口文件的统一基础库进行依赖;(业务开发方开发阶段只需要依赖接口文件依赖库,在主项目集成测试阶段依赖所有业务组件进行测试)
-
接口和实现类的的对应注册须用代码完成,由中间件去控制服务实现类的生成;
(通用问题:复杂参数传递 key值的硬编码问题)
(4)组件维护问题?
-
组件服务接口的设计:
-
最小化原则;
-
命名规范;
-
版本发布:
-
版本号规范:http://semver.org/
-
持续集成,通过脚本完成:https://github.com/fastlane/fastlane
三、关于组件化的思考和总结
MGJRouter+ModuleManager方案 (蘑菇街方案)
CTMediator+Target-Action方案 (反革命方案)
(1)主要解决本地业务组件之间的通信问题
组件化主要还是解决本地业务组件间的调用,至于跨App或者Hybrid页面通过openUrl方式调用页面和服务的方式其实是可以拆分成两个步骤的问题:特定模块解析处理+中间件调用。跨App通过info.plist配置的scheme跳转进入,hybrid页面通过JSBridge框架跳转进入,这部分都有特定的模块去解析完成。在特定的模块中是否要调用其它业务组件的页面或者服务由特定模块自行决定,这不是组件化中间件要去完成的事情。
(2)从工程代码层面来说,组件化就是通过中间件解决组件间头文件直接引用、依赖混乱的问题;
从实际开发来说,组件之间最大的需求就是页面跳转,需要从组件A的pageA1页面跳转到组件B的pageB1页面,避免对组件B页面ViewController头文件的直接依赖。其次就是服务的调用,服务调用模块绝不是为了解决url跳转的问题,只是服务调用方式可以用来解决页面跳转的需求,但是没有url跳转方案成本低。所以才有了蘑菇街方案的MGJRouter和ModuleManager的class-protocol方案的区别;而反革命的方案仍然用Target-Action方案来解决页面跳转问题,成本稍大;而且url跳转和服务调用是两种不同的组件间通信需求,用两种不同的方式来完成更有区分度。
(3)纯中间件只负责挂接节点的通信问题,不应涉及挂接点具体业务的任何逻辑。
中间件如果涉及到具体的业务逻辑,势必造成中间件对业务模块的直接依赖,所以中间件只需要抽象出业务通信的基本职责,规定好协议接口,完成调度功能即可。
而每个挂接节点(这里指业务组件)遵循中间件的协议完成挂接工作,当然这会造成挂接节点对中间件的协议依赖;调用方同样也必须通过挂接点提供的方法将调用操作push到中间件上,而不用管具体的调用过程,这样也是挂接节点依赖中间件,业务逻辑并没有直接依赖中间件。这就是之前阿里无线分享的bus总线的思路,通过这种思路即使切换或者去掉中间件,都只需要在挂接节点中进行修改就可以完成,避免了对业务逻辑代码的直接调用修改。
至于去掉中间件,应用仍然能够跑的命题? 如果没有任何代码的修改,就相当于把解藕的桥梁给拆除了,再牛逼的框架也不能满足。
- 反革命框架的调用方直接依赖中间件提供的调用方法,拆除中间件,至少需要修改调用方法。
(4)中间件是否应该解决组件对外披露url调用和服务接口信息?
中间件解决了组件间的通信解藕问题,势必会将组件对外提供调用的信息隐藏起来,不然就不能达到解藕通信的目标。
蘑菇街方案的披露方法:
-
url短链在后台管理,自动生成可查看的.{h,m,java}文件,开发人员通过这个文件进行查看,代码文件跟文档功能类似;无法解决参数key、类型的问题;
-
服务调用接口统一放到PublicProtocol.h文件上,其它所有业务组件均需要依赖这个文件;
(是否把url短链和publicProtocol文件统一放到一个repo里,其实就相当于说明文档的作用)
反革命方案的披露方法:
-
通过依赖中间件的category(target)方式,将业务组件的所有调用都通过category的方法暴露出来;
-
优点:解决了url参数key、类型检查的问题;通过Target-Action方式同时解决了url短链和服务调用的通信需求,而且更加适合程序猿的风格来解决问题。
四、我们的组件化方案
之前听阿里的组件化分享之后,自己做了一套有关Bus总线的方案,但是在具体的产品使用过程中用起来还是麻烦,在项目中推广起来难度还是比较大。特别是关于组件对外披露信息的部分,到现在都没有一个好的思路,虽然反革命的方案解决了披露的问题,但是我觉得扩展性和可维护性上还是比较差。
git开源地址:https://github.com/Lede-Inc/LDBusBundle_IOS.git
最近研读几个大神的博客和讨论之后,有了一些新的思路,希望能够继续按照bus+category的思路上去专研一下,希望能够一个真正适合在项目里推行起来的方案。
最近在参考大神们的讨论和之前的LDBusBundle方案基础上上,提炼出了一个适合中小型应用的LDBusMediator中间件,正逐渐在项目中使用。
博客介绍:http://www.jianshu.com/p/196f66d31543
中间件Git开源地址:https://github.com/Lede-Inc/LDBusMediator.git
[
阅读世界,共赴山海
423全民读书节,邀你共读
](https://blog.csdn.net/programmer_editor/article/details/124121252?utm_campaign=marketingcard&utm_source=ZY_FlyWay&utm_content=72868879)
最后
小编综合了阿里的面试题做了一份前端面试题PDF文档,里面有面试题的详细解析
最后
小编综合了阿里的面试题做了一份前端面试题PDF文档,里面有面试题的详细解析
虽只说了一个公司的面试,但我们可以知道大厂关注的东西并举一反三,通过一个知识点延伸到另一个知识点,这是我们要掌握的学习方法,小伙伴们在这篇有学到的请评论点赞转发告诉小编哦,谢谢大家的支持!