简单性和模块化是软件工程的基石;分布式和容错性是互联网的生命。 《Tim Berners-Lee》
什么是模块化
个人认为模块化是对整个项目的解耦以及项目维护带来极大的优势。而且在协同开发的导致各种各样的问题(例如文件冲突等问题)
模块化还可以实现模块内自管理,模块内你可以自由发挥你的管理方式,不管你是mvp,mvvm。每个人维护若干个模块。
基本思路
之前有阅读微信 Android 模块化架构重构实践,其中提出的pin工程让我眼前一亮,原来还可以这么搞。同时也参考了一下饿了么移动App的架构演进,那么其中的Excalibur系统
也是一大亮点。
结合各大厂的架构演进,再加上即将要开展的新项目的情况,最后决定使用接口+SDK
方式,进行模块化管理。
为什么不用类似微信的pin工程
,原因是如果是要对现有的项目实现模块化,那么pin
是一个非常好的过度方案,你无需进行繁杂的模块管理,直接在现有的工程上,以最快最少的方式就可以实现pin工程
,最后完成module的转变。但如果我是全新的项目,则接口+模块会是更好的选择。
基本架构图
- 最底层是Common: 里面主要是核心模块、公共UI模块以及第三方库
- apis: 这里存放所有模块的暴露出来的接口
- Bridge: 桥接器,里面可以按需进行模块的注册
- App: App只依赖Bridge和Apis,模块的实现并不引用。
这样下来,就可以根据需要输出不同的App,特别像那种会进行更换厂商提供的sdk的,或者要求输出不同模块需要单独变成一个App的,简直是天大的福音。
项目结构
首先,我们假设要集成某厂商的摄像头。我们定义一个plugin_camera模块,里面是摄像头具体实现,里面只有一个简单的方法echo
1 | public class Camera implements ICamera { |
同时在Apis里面定义好要暴露的echo方法
1 | public interface ICamera { |
然后桥接器里面进行模块的桥接
1 | public class Bridge { |
最后在主app里面直接使用
1 | Bridge bridge = Bridge.getInstance(); |
如果某天产品经理跟你说,需要把Camera单独出来做成一个App,你只需要在plugin_camera
模块里面增加对应的mainactivity
和对应的Manifest.xml
就可以了。
注意事项
- 上面没有详细说明怎么实现模块App,但原理也很简单,新建模块的时候,你需要把模块内的
build.gradle
修改成
1 | if (!isOpenCamera.toBoolean()) { |
继续在模块内生成一个debug用的Manifest.xml
和release用的Manifest.xml
。
然后在根目录下的gradle.properties
里面增加以下内容
1 | isOpenCamera=false |
实现具体请看源码吧。
- Bridge和Apis其实可以合并成一个模块也是可以的。
- Bridge里面的模块注册使用的方式是反射,但这只是为了演示作用,其实如果真的在实际开发过程中,会使用模块自动注册的方式,而且像Demo里面直接反射。如果还用了
ARoute
的话,那么其中也包含了自动注册。但个人更加倾向的是使用gradle插件,通过操作字节码的方式来实现自动注册的。当然也可以使用AOP的方式来注册。后期会详细说说这几种方式的却别。
用一句网上看到的话来进行总结吧,我觉得非常好笑,也觉得非常的有道理的一句话。
任何软件工程遇到的问题都可以通过增加一个中间层来解决!
项目已上传github