模块化和组件化的区别

前言

前段时间反复研读了蘑菇街 App 的组件化之路、蘑菇街 App 的组件化之路·续和iOS应用架构谈 组件化方案,然后又找到了其它一些研究组件化、模块化方案的文章,但是总觉得差点什么,所以还是决定从头开始思考。文章的标题起的好宽泛,感觉给自己挖了个深坑-。-,其实只是自己对组件化、模块化的一些看法、总结。

为什么

先总结一下为什么要大动干戈的对代码进行分模块、拆组件。

代码量膨胀,不利于维护,更不利于新功能的开发

现在随便开发一个App的代码行数都是数以万计的,如果不对代码做合理的拆分,那简直就是灾难性的,估计只有最初的开发人员知道如何维护修改,如果换人开发的话,难以下手,更不用说开发新功能了。

不同业务代码耦合严重,难以多人合作,职责不分明

多人一起开发时,如果代码结构、模块化的不好,就很难对不同业务划分出分界线,难以明确各自的职责,牵一发动全身,出了问题更是容易相互扯皮(这个时候只能说一句“怪我咯o(╯□╰)o”),更不用提合并代码时的冲突了。

所以,合理的组织代码,划分模块、拆分组件是项目可以高效迭代的基础。

疑问

那到底什么是模块化、组件化?查资料的时候一会儿模块,一会儿组件,有什么联系,有什么区别?有人说这只是叫法习惯问题,知道大概意思就好,不用咬文嚼字,但是总觉得没有个“定义”感觉不踏实,所以还是求助了万能的维基百科=。=

模块化

维基百科的Modular programming的开头定义如下:

Modular programming is a software design technique that emphasizes separating the functionality of a program into independent, interchangeable modules, such that each contains everything necessary to execute only one aspect of the desired functionality

接着,在Key aspects部分的开头也说了:

With modular programming, concerns are separated such that modules perform logically discrete functions, interacting through well-defined interfaces.

可以总结为:模块化的目的在于将一个程序按照其功能做拆分,分成相互独立的模块,以便于每个模块只包含与其功能相关的内容,模块之间通过接口调用。

组件化

组件化跟模块化是很类似的,都是主要为了对一个系统做拆分,同时,组件还具有其他属性,如可替代性(substitutable),通过接口(interface)访问,可重用性(Reusability)等,读者可自行阅读。

对比

难道模块化跟组件化真的是完全一样的?的确,很多时候两者的概念完全可以相互替换,在实践中更是经常混用。

在求助谷歌,甚至阅读了大量的前端技术等其它技术领域的组件化、模块化的文章后,我觉得如果真要将它们两者做个对比,大概总结如下:

  • 模块化强调的是拆分,无论是从业务角度还是从架构、技术角度,模块化首先意味着将代码、数据等内容按照其职责不同分离,使其变得更加容易维护、迭代,使开发人员可以分而治之。

  • 组件化则着重于可重用性,不管是界面上反复使用的用户头像按钮,还是处理数据的流程中的某个部件,只要可以被反复使用,并且进行了高度封装,只能通过接口访问,就可以称其为“组件”。

当然,并不是说模块就不能被复用,还是要根据实际情况来看,使系统更加容易维护,开发更加方便,才是最终目的。

如何拆分

无论是模块化还是组件化,首先肯定是做拆分,但是如何拆分?怎么下手?依照什么标准?
下面简单总结一些方法。

横向拆分业务、功能模块

很多时候,一个完整的软件程序是同时为多种业务服务的,所有可以优先按照业务的不同,将整个系统进行拆分。

如一个电商类型的App,就可以分出商品浏览模块、订单模块、购物车模块、消息模块、支付模块等。又如微信这种社交型应用,可以拆分出联系人模块、朋友圈模块、聊天模块、消息模块等。

其实就是从用户使用的角度,按照功能的不同划分模块,当然,这种业务模块是要由各种技术模块作支撑的。

纵向拆分技术、架构模块

如果脱离业务,只从技术角度来看,则可以尝试纵向对系统拆分模块

其实这里的纵向拆分跟对系统的架构做分层有点像=。=,现如今只要需要联网请求API的App都免不了有网络请求、数据缓存、数据加工处理、数据展示、反馈用户操作等行为,所有这些环节层层递进才能完成一个功能。

从界面入手,拆分可视化组件

很多时候,像界面里面的“搜索框”、“头像按钮”、“内容框”和显示提示用的“加载中”HUD,甚至整个内容的Cell,都是可能在很多地方出现的,而且本身的样式、功能比较集中。
如头像可能要支持点击跳转,头像图片圆角,内容框有特定的Padding和字体大小等,所以可以将这些界面上的元素“提”出来,单独封装成一个组件,供整个App复用。


小节

首先,可以肯定的是,组件化和模块化的中心思想都是分而治之。目的都是将一个庞大的系统拆分成多个组件或者说是模块。

组件化就是基于可重用的目的,将一个大的软件系统按照分离关注点的形式,拆分成多个独立的组件,主要目的就是减少耦合。
组件化的目的是为了解耦,把系统拆分成多个组件,分离组件边界和责任,便于独立升级和维护。

模块化的目的是为了重用,模块化后可以方便重复使用和插拨到不同的平台,不同的业务逻辑过程中