组件化方案:JIMU之再看组件化

近几年,组件化和插件化在Android开发领域中一直是较为热门的议题,笔者也参与了组件化框架项目:JIMU,原DDComponentForAndroid,对组件化也算偶有心得。

本文不去做JIMU的具体介绍,也不将其和Andromeda(iqiyi开源组件化项目)、微信的API化轻量级方案等进行对比,仅结合这半年多来在JIMU讨论组中和各位同行的一些交流、一些issue的讨论,总体反思一下组件化

其实张明庆老哥在JIMU的系列文档中零碎的提到过不少内容,之所以还有这一篇,是笔者觉得:在诸位同行在进行组件化实施探索的过程中出现的一些问题、困惑,还是对组件化理解的不够透彻导致的

模块化 & 组件化 或 插件化

请注意本处副标题中的三个名字,我们常常将组件化和插件化技术进行对比,这是一组概念,但是我们往往忽略掉了“模块化”,其实模块化才是组件化或插件化的前提。

简述一下计算机领域中广义的模块化含义:

以功能块为单位进行程序设计,实现其求解算法的方法称为模块化

而从方法论上看,模块化的核心要义就是要做到:构建功能相对独立的子系统,并通过子系统组合成一个实际产品。

而组件化的定义:(今天Wikipedia上不去了,援引百度百科)

组件化是指解耦复杂系统时将多个功能模块拆分、重组的过程,有多种属性、状态反映其内部特性。

可以说,组件化是进行一种系统解耦时、具有特定形式的模块化过程。

DEMO:在狭义讨论中

  1. 在软件设计中,我们“整理”出一个局部子系统,其内部实现了:

    • 下层:使用线程池管理数据库CURD、文件存储等数据持久化的耗时任务,并暴露任务的管理
    • 中层:DAO接口及其实现类的注册、通过DAO接口发现实现类的IOC容器(实现类对象的生命周期管理此处忽略讨论)
    • 上层:DAO接口定义和DAO接口实现

    这里我们可以将下层和中层划归为一个模块:比如叫“持久层操作核心模块”,将整个可以称为:“数据持久化模块”;在项目的整体分层划分中,我们可能更多的去用“数据持久化模块”去描述这个子系统,但其中的上层其实是做具体业务实现了,而“持久层操作核心模块”的讨论意义在这里更大一些。

    假如、我提出一个比较极端的骚操作:将整个项目中所有的持久化业务集中在一起(前文中的“上层”),包括“持久层操作核心模块”,放在一个具体的Module中,将其称为:“持久化业务组件”,显然、这并没有什么错,但是这个做法很可能造成灾难

    但是将“持久层操作核心模块”称为:“持久层操作核心组件”的话,大家一定不会接受这个说法,它还没有上升到可以被称为组件的程度。打个比方,组件仅到分子的程度、模块可以到原子的程度。

我们先快速的抛出一个结论:要做好组件化一定要做好模块化,包含具体业务并通过接口向外暴露业务的模块可以被称为组件。

  1. 粒度问题,真实案例:考虑到改造时的风险性,某位朋友(就叫Tom好了)在组件化实施过程中并没有做前文中的“持久化业务组件”,而是将其散落在各个“实际功能系统组件”中。例如,Tom定义并实现了“用户系统组件”,其中包含了用户登录注册等等等等你下意识想到的业务,其中包含了用户设置的持久化业务,而在另一个组件中,需要使用到这个设置,最开始我们就“JIMU中组件初始化顺序可能影响到业务”进行讨论、最终讨论到组件化的粒度问题。

    在1中,我们所看到的“持久化业务组件”就是一个粒度很细的例子,在Tom的案例中,就是一个粒度较粗的例子,粒度的粗细问题是没有一个定论的,只能根据实际情况选择一个平衡点,在Tom提供的案例中,可以在用户组件中定义业务接口,将业务暴露出去供其他组件使用,这并没有违反组件化原则,但是当这个“用户组件”越来越大时,将诸如:查询用户设置、查询用户信息等业务再拆分出一个独立的业务组件是有必要,这也是重构的一个适应症。

    组件化革命不一定要一步到位、干净彻底,但一定要朝着正确的方向稳步发展。


在前面两个DEMO中我们对组件化和模块化有了一个感性的认识,我们再正儿八经的看概念

概念和方法论

模块化编程:
采用模块式开发方式,单个组件包括模板,数据结构,程序,样式四部份。
组件的接口表达了由该组件提供的功能和调用它时所需要的参数。
组件是可以单独开发、测试。允许多人同时协作,编写及开发、研究不同的功能模块。--百度词条

基于组件的软件工程(Component-based software engineering,简称CBSE)或基于组件的开发(Component-Based Development,简称CBD)是一种软件开发范型。它是现今软件复用理论实用化的研究热点,在组件对象模型的支持下,通过复用已有的构件,软件开发者可以“即插即用”地快速构造应用软件。这样不仅可以节省时间和经费,提高工作效率,而且可以产生更加规范、更加可靠的应用软件。-- wikipedia

百度词条中的概念,在Android中进行印证,组件包含“布局文件”(模板),数据类(广义的数据结构),程序,资源、样式。
JIMU sample工程中的ComponentService-Module,其中定义了组件提供的功能和入参出参牵涉到的数据类(基础类型除外)。

在wikipedia的概念中,我们抓住几个关键词:“组件对象模型”、“复用”、“即插即用”。

组件对象模型最早应该是在Windows开发中兴起的(未经考证),Component Object Model,他是用来描述一个组件的,不过不是用一个实际的实现类对象来描述的,而是通过接口规范来描述的,对照JIMU,其组件对象模型是APPLike生命周期接口和ComponentService中的业务API接口。

组件级复用有这样的要求:具有相对独立的业务环境,若对外界环境有所依赖,应该通过组件对象模型。通俗的说就是要解耦。

复用已有的构件(构成组件,而非构建)上,JIMU做的也非常出色,他不仅能对源码级支持(这是必要的),同时对已经构建过的构件同样能做到复用。

“即插即用”:Plug-And-Play 本身是硬件层的一个词,在这里大体可以理解为:“修改配置或者输入命令、将构件纳入应用软件中,它就能直接使用而不需要过多的人工干涉”。在JIMU中,需要人维护配置表,做一点做的还不够好,但是在运行期间的热插拔方面做的还可以

再回到百度词条,组件为何是可以单独开发、测试的。上文我们提到了组件对象模型、并且提到了组件解耦的要求;对于外部而言,组件就是一个对象模型,访问它只需要通过接口,而该组件对外部环境的依赖也是通过对象模型。所以、组件是完全独立的,他的实现和外界是无关的,即所谓独立开发。组件要运行是需要运行时环境的,只要满足了运行时环境、组件就可以运行以及测试,而组件对其他组件的依赖是通过组件对象模型的,意味着可以Mock,或者自己写Dummy实现(搞事情),进而独立测试逻辑(无论是单元测试、还是人工、自动化集成测试)。

从方法论上来说,组件化实现需要做这些:

  • 一个组件化构建工具。在必要的时候满足:组件构建时具有运行时环境;在构建时的人工干预越小越好,最好能通过命令参数“即插即用”。
  • 项目按照模块化进行设计、组件按照组件对象模型标准设计。

JIMU中关于独立测试、构建的具体操作请参考WIKI相关内容

直接使用JIMU

改造流程
改造流程
image link

这张图是我之前画的,按照图示任务主线可以比较从容的完成项目改造,从容未必简单,仅仅是目的明确所带来的从容。即使不使用JIMU(或者原来的DDComponentForAndroid)以下内容也是必要的:

  • 各种资源的整理,公共基础资源独立,私有资源跟随组件。某些资源可能在两三个Module中出现,但是作为公共资源觉得膈应的也可以改名后采取冗余
  • 公共库和私有库的区分。
  • 梳理组件、但是先进行模块化。对于不符合模块化要求的代码,先做模块化改造,至少现在还没有实际的代码边界,修修改改代码还能跑
  • 摘选合适的模块分离为组件,已经满足模块化的代码应该比较轻松了
  • 处理组件化代码隔离带来的一些问题。这些问题可能并不存在,例如模块化过程中对于UI跳转也进行了彻底的解耦,那么组件化隔离时多半不会受到代码边界的影响
  • 不停的拆分完善,并为单独组件补充高质量的测试,可以在迭代过程中减少不必要的错误

切忌

组件化开发一定要做到组件独立开发,可以多个组件同时独立开发,但一定要独立开发,这个独立不是指单人力,而是指组件的开发过程中,不要依赖还在开发中的组件对象模型。
组件对象模型的定义优先于组件对象的实现,诸如:组件对象模型的定义改了而使用者不知道的担心必然是冗余的。

写在最后

且不和其他项目做仔细的比较,JIMU在组件化课题中还有很多不足的地方,笔者也在为JIMU做一些力所能及的工作,欢迎各位对项目点个Star、发现并提出Issue、提交有价值的PR;也欢迎进群进行交流和讨论。

JIMU的讨论群,(QQ)群号693097923,欢迎大家加入:


扫码进QQ群
扫码进QQ群
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,795评论 25 707
  • 夜了 酸酸的 多了思念 多了渴望 渴望马上见到您 一一母亲 母亲 我看到您了 我看到了您站直的脚 我看到了您 会走...
    小草_d5ad阅读 403评论 12 35
  • 01 微博热搜里,孙俪被曝出从《甄寰传》、《芈月传》到现在的《那年花开月正圆》,三部戏的片酬高达1.7亿元,本来以...
    莫小葵阅读 1,325评论 2 4
  • import语句 和 C 一样,Objective-C 也使用头文件来包含结构体、符号常量和函数原型等元素的声明。...
    Junetaurus阅读 13,186评论 0 5
  • 悬绝无径 亘古的矗立 凝视 苍老了岁月 炙热 化为冰冷和坚硬 已经忘却了 是沉沦 还是崛起 汹涌的海 从未停止过撞...
    青漄阅读 271评论 4 8