一种低侵入性的组件化方案 之 组件化须要考虑的几个问题

github开源地址 github.com/beyondxia/m…git

    上一篇文章,咱们讨论了目前传统的解耦方案和通讯机制。其实解耦只是咱们实施组件化的第一步,要作到真正的组件化,还须要针对业务模块作代码的独立分仓,lib话(aar化),模块可以以aar库的形式集成到主APP,进一步提供模块的独立性,甚至能够及其方便的进行组件的安装和卸载。github

  1. 如何确保模块之间绝对的解耦完成
  2. 如何进行代码的分仓,中间可能会涉及到哪些问题
  3. 如何极简的作到模块的接入和下线需求。

    咱们先从第二个问题开始讨论,就是【如何进行代码的分仓,中间可能会涉及到哪些问题】。bash

    在我所开发的几个大型项目当中,涉及到组件化的需求,都是在项目有小到大发展到必定程度,业务模块愈来愈多,开发人员数量达到必定数量时,才开始对项目进行组件化的规划。这就意味着,项目刚开始时,咱们全部的模块都是在一个代码仓内进行开发的,开发人员也都是在一块儿开发,模块界限不是很明确。这种状况下,咱们再对模块进行组件化拆分,会涉及哪些问题呢:app

  1. 好比A模块但愿获取B模块的model数据、自定义view、fragment等,可是这些结构的定义是在B中定义的,A中没法找到定义;
  2. 再好比几个模块须要共享一些资源 文件(如图片,layout,value等)等,咱们不可能把相同的资源每一个模块中都保留一份。

    咱们知道,模块功能暴露以接口方式暴露,接口是须要放中间服务层的,以下图:框架

    针对上面的问题,咱们也能够和服务接口同样,把相应的共享数据放在服务层。只不过共享的资源文件,咱们建议以独立的module库放在服务层,各个业务模块根据需求能够选择是否依赖该module库。组件化

    接下来,咱们再来讨论第一个问题【何确保模块之间绝对的解耦完成】这儿又分为两种状况:post

  1. 如何保证子模块之间没有任何依赖
  2. 如何保证主app对子模块是没有依赖的。

    对于第一个问题,只要子模块的依赖依赖列表(gradle- dependencies)中没有对其余模块的依赖,就能够绝对保证本模块和其余模块之间是绝对解耦的。gradle

    第二个问题,如何保证主APP对子模块没有绝对的依赖呢,咱们知道,主APP若是但愿集成子模块,就必须依赖子模块。咱们可使用新版gradle插件依赖选项runtimeOnly,只在运行时可使用,编译时依赖直接报错。ui

经过这种方式,能够保证各个模块和主App之间达到绝对的解耦。spa

    下面咱们接着讨论第三个问题【如何极简的作到模块的接入和下线需求】:

    对一个新的业务模块,咱们要可以一个极简的方式接入咱们的主APP,这很重要,这决定这业务方的接入成本和接入意愿。这就要求咱们的框架(特别是解耦框架)可以在极小的代码改动量的状况下,可以快速接入主APP,这部份内容,咱们会在后续的文章中详细说明:一种低侵入性的组件化方案 之 传统组件化方案的问题

    那若是咱们但愿在某些特定的场景或版本中,下线某些业务模块,那该怎么办呢?这里咱们须要考虑两个问题:

  1. 代码打包中,能够选择性的打包某些业务模块
  2. 下线后,对于正常的模块间的调用,app的稳定性要能获得保证,不能由于调用了一个不存在的模块而致使APP编译不经过或应用运行crash。针对问题1,很好解决,主APP中选择性的依赖某些模块便可。第二个问题,就对咱们的框架有必定的要求了,咱们的解耦,总线,路由框架要可以有必定的异常处理机制,好比:对于某些可能要下线的模块,其余模块在调用的以后,框架能够抛出一个模块不存在的异常,调用方必须捕获该异常。

服务提供:

public abstract class LoginService extends PAService implements ILogin {
	public static ILogin get() throws NoServiceException {
		return getService(SERVICE_NAME);
	}
}
复制代码

调用方:

String username = null;
try {
    username = LoginService.get().getUserName();
} catch (NoServiceException e) {
    e.printStackTrace();
}
复制代码

上一篇:一种低侵入性的组件化方案 之 APP组件化简介

下一篇:一种低侵入性的组件化方案 之 传统组件化方案的问题

相关文章
相关标签/搜索