模块化/组件化
- 通过模块化/组件化组织代码,面向接口编程,尽可能做到高内聚、低耦合、重复用。
- 模块可分为多种类型,一般分为:基础库(日志打印、网络请求、图片加载等)、三方包(微信登录、统计分析、消息推送等)、业务组件(APP外壳、会员中心、商城等)。
- 常见组件间通信方式:直接依赖(耦合太重,不推荐)、事件或广播(难以溯源,不推荐)、路由(如 ARouter)、面向接口(推荐)。
模块化/组件化的优势:
- 结构清晰:业务独立,每个业务作为单独的组件,代码实现分离,不会搅在一起。
- 便于协作:每个开发人员只关心自己负责的模块/组件,每个模块/组件作为一个子工程,没有太多的耦合。
- 便于维护:各模块/组件管理自己的代码、布局、资源,主工程可以方便添加与移除。
组件化开发的实施步骤
- 1、在接口层(
contract
),每个业务模块(如统计分析)定义相关接口(如StatisticContract
)并继承自IContract
约定好要对外提供的方法。
public interface IContract {
}
public interface StatisticContract extends IContract {
void setup(@NonNull Application application, @NonNull String appKey, @NonNull String channel,
boolean agreeEulaOrPolicy, boolean isRelease);
void onEvent(@NonNull String eventID, @NonNull Map<String, Object> map);
}
- 2、具体的业务组件如友盟统计(
umeng
)依赖接口层(contract
),对约定的接口进行实现(如UMengImpl
),同时通过注解ContractImpl
为StatisticContract
指定该实现类。若在将来要更换成极光统计(jiguang
),则重新指定实现类即可。
implementation project(':contract')
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ContractImpl {
String className();
}
@ContractImpl(className = "com.github.gzuliyujiang.umeng.UMengImpl")
public interface StatisticContract extends IContract {
}
- 3、其他使用方都依赖接口层(
contract
),且具体的业务模块(如umeng
)必须通过runtimeOnly
进行代码隔离,并通过接口管理器(ContractMaster
)获取所需的接口(如StatisticContract
)使用。
implementation project(':contract')
runtimeOnly project(':umeng')
public final class ContractMaster {
@NonNull
public static <T extends IContract> T get(@NonNull Class<T> contract) {
}
}
ContractMaster.get(StatisticContract.class)