Files
mkdocs/docs/android面试/系统架构/模块化设计.md
2026-01-15 11:53:37 +08:00

14 KiB
Raw Permalink Blame History

模块化设计

目录


模块化概念

什么是模块化?

模块化是将应用程序按照功能或职责拆分成多个独立的模块Module每个模块有明确的职责和接口。

模块化 vs 组件化

特性 模块化 组件化
粒度 较细,按功能拆分 较粗,按业务拆分
独立性 模块可以独立编译 组件可以独立运行
复用性 模块可以在项目内复用 组件可以在项目间复用
适用场景 中大型项目 大型项目、多团队协作

模块化架构图

┌─────────────────────────────────┐
│         App Module               │
└─────────────────────────────────┘
           │
    ┌──────┴──────┐
    │             │
┌───▼───┐    ┌───▼───┐
│模块A  │    │模块B  │  ← 功能模块
│(Module)│    │(Module)│
└───┬───┘    └───┬───┘
    │             │
    └──────┬──────┘
           │
    ┌──────▼──────┐
    │  Base Module │  ← 基础模块
    └──────────────┘

模块划分

1. 按功能划分

app/
├── app/                    # 主应用模块
├── module_network/         # 网络模块
├── module_database/        # 数据库模块
├── module_cache/           # 缓存模块
├── module_image/           # 图片加载模块
├── module_ui/              # UI 组件模块
└── base/                   # 基础模块
    ├── base_common/        # 公共工具
    └── base_core/          # 核心功能

2. 按层次划分

app/
├── app/                    # 表现层
├── domain/                 # 领域层
│   ├── domain_user/       # 用户领域
│   └── domain_order/       # 订单领域
├── data/                   # 数据层
│   ├── data_repository/   # 数据仓库
│   └── data_source/       # 数据源
└── base/                   # 基础层

3. 按业务划分

app/
├── app/                    # 主应用
├── feature_login/          # 登录功能
├── feature_home/           # 首页功能
├── feature_user/           # 用户功能
└── shared/                 # 共享模块
    ├── shared_network/     # 网络共享
    └── shared_ui/          # UI 共享

模块划分原则

  1. 单一职责:每个模块只负责一个功能
  2. 高内聚低耦合:模块内部高内聚,模块间低耦合
  3. 接口清晰:模块间通过接口通信
  4. 依赖方向:上层模块依赖下层模块

模块依赖管理

1. 依赖关系

App Module
    ↓
Feature Modules功能模块
    ↓
Shared Modules共享模块
    ↓
Base Module基础模块

2. build.gradle 配置

// app/build.gradle
dependencies {
    // 依赖功能模块
    implementation project(':feature_login')
    implementation project(':feature_home')
    implementation project(':feature_user')
    
    // 依赖共享模块
    implementation project(':shared:shared_network')
    implementation project(':shared:shared_ui')
}

// feature_login/build.gradle
dependencies {
    // 功能模块依赖共享模块
    implementation project(':shared:shared_network')
    implementation project(':shared:shared_ui')
    
    // 功能模块依赖基础模块
    implementation project(':base:base_common')
}

// shared_network/build.gradle
dependencies {
    // 共享模块依赖基础模块
    implementation project(':base:base_common')
}

3. 避免循环依赖

// ❌ 错误:循环依赖
// module_a 依赖 module_b
// module_b 依赖 module_a

// ✅ 正确:单向依赖
// module_a 依赖 module_b
// module_b 不依赖 module_a

4. 依赖版本管理

// 项目 build.gradle
ext {
    versions = [
        'compileSdk': 30,
        'minSdk': 21,
        'targetSdk': 30,
        'kotlin': '1.5.0',
        'retrofit': '2.9.0',
        'okhttp': '4.9.0'
    ]
}

// 模块 build.gradle
android {
    compileSdkVersion versions.compileSdk
    defaultConfig {
        minSdkVersion versions.minSdk
        targetSdkVersion versions.targetSdk
    }
}

dependencies {
    implementation "com.squareup.retrofit2:retrofit:${versions.retrofit}"
    implementation "com.squareup.okhttp3:okhttp:${versions.okhttp}"
}

模块间解耦

1. 接口隔离

// 定义接口
public interface INetworkModule {
    <T> void request(String url, Class<T> clazz, Callback<T> callback);
}

// 模块实现接口
public class NetworkModule implements INetworkModule {
    @Override
    public <T> void request(String url, Class<T> clazz, Callback<T> callback) {
        // 实现网络请求
    }
}

// 其他模块使用接口
public class LoginModule {
    private INetworkModule networkModule;
    
    public LoginModule(INetworkModule networkModule) {
        this.networkModule = networkModule;
    }
    
    public void login(String username, String password) {
        networkModule.request("/login", User.class, callback);
    }
}

2. 依赖注入

// 使用 Dagger2 进行依赖注入
@Module
public class NetworkModule {
    @Provides
    @Singleton
    INetworkModule provideNetworkModule() {
        return new NetworkModuleImpl();
    }
}

@Module
public class LoginModule {
    @Provides
    LoginService provideLoginService(INetworkModule networkModule) {
        return new LoginService(networkModule);
    }
}

// 使用
@Component(modules = {NetworkModule.class, LoginModule.class})
public interface AppComponent {
    void inject(MainActivity activity);
}

3. 事件总线

// 使用 EventBus 解耦
public class NetworkEvent {
    private String eventType;
    private Object data;
    
    public NetworkEvent(String eventType, Object data) {
        this.eventType = eventType;
        this.data = data;
    }
}

// 模块A发送事件
EventBus.getDefault().post(new NetworkEvent("login_success", user));

// 模块B接收事件
@Subscribe(threadMode = ThreadMode.MAIN)
public void onNetworkEvent(NetworkEvent event) {
    if ("login_success".equals(event.getEventType())) {
        // 处理登录成功事件
    }
}

4. 服务发现

// 服务注册中心
public class ServiceRegistry {
    private static ServiceRegistry instance;
    private Map<Class, Object> services = new HashMap<>();
    
    public static ServiceRegistry getInstance() {
        if (instance == null) {
            synchronized (ServiceRegistry.class) {
                if (instance == null) {
                    instance = new ServiceRegistry();
                }
            }
        }
        return instance;
    }
    
    public <T> void register(Class<T> clazz, T service) {
        services.put(clazz, service);
    }
    
    public <T> T get(Class<T> clazz) {
        return (T) services.get(clazz);
    }
}

// 模块注册服务
ServiceRegistry.getInstance().register(INetworkModule.class, new NetworkModuleImpl());

// 其他模块获取服务
INetworkModule networkModule = ServiceRegistry.getInstance().get(INetworkModule.class);

模块化实现

1. 项目结构

project/
├── app/                    # 主应用模块
│   └── build.gradle
├── feature_login/          # 登录功能模块
│   └── build.gradle
├── feature_home/           # 首页功能模块
│   └── build.gradle
├── shared/                 # 共享模块
│   ├── shared_network/    # 网络共享
│   └── shared_ui/          # UI 共享
├── base/                   # 基础模块
│   ├── base_common/        # 公共工具
│   └── base_core/          # 核心功能
└── build.gradle           # 项目配置

2. 模块配置

// feature_login/build.gradle
android {
    compileSdkVersion 30
    
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"
    }
    
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    // 依赖共享模块
    implementation project(':shared:shared_network')
    implementation project(':shared:shared_ui')
    
    // 依赖基础模块
    implementation project(':base:base_common')
    
    // 第三方库
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
}

3. 模块接口定义

// base_common/src/main/java/com/example/common/INetworkModule.java
public interface INetworkModule {
    <T> void request(String url, Class<T> clazz, Callback<T> callback);
}

// shared_network/src/main/java/com/example/network/NetworkModuleImpl.java
public class NetworkModuleImpl implements INetworkModule {
    @Override
    public <T> void request(String url, Class<T> clazz, Callback<T> callback) {
        // 实现网络请求
    }
}

4. 模块初始化

// Application
public class MainApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        
        // 初始化基础模块
        initBaseModules();
        
        // 初始化共享模块
        initSharedModules();
        
        // 初始化功能模块
        initFeatureModules();
    }
    
    private void initBaseModules() {
        // 初始化基础模块
    }
    
    private void initSharedModules() {
        // 注册共享模块服务
        ServiceRegistry.getInstance().register(
            INetworkModule.class, 
            new NetworkModuleImpl()
        );
    }
    
    private void initFeatureModules() {
        // 初始化功能模块
    }
}

模块化最佳实践

1. 模块职责清晰

// ✅ 好的模块:职责单一
// network_module只负责网络请求
public class NetworkModule {
    public <T> void request(String url, Class<T> clazz, Callback<T> callback) {
        // 网络请求逻辑
    }
}

// ❌ 不好的模块:职责过多
// network_module既负责网络请求又负责数据解析、缓存等
public class NetworkModule {
    public void request() { }
    public void parse() { }
    public void cache() { }
}

2. 接口设计

// ✅ 好的接口:职责单一,参数清晰
public interface INetworkModule {
    <T> void request(String url, Class<T> clazz, Callback<T> callback);
}

// ❌ 不好的接口:职责过多,参数复杂
public interface INetworkModule {
    void request();
    void parse();
    void cache();
    void upload();
    void download();
}

3. 依赖管理

// ✅ 好的依赖:清晰、单向
// feature_login → shared_network → base_common

// ❌ 不好的依赖:循环依赖
// feature_login → feature_home
// feature_home → feature_login

4. 版本管理

// ✅ 好的版本管理:统一管理
ext {
    versions = [
        'compileSdk': 30,
        'retrofit': '2.9.0'
    ]
}

// ❌ 不好的版本管理:分散管理
// 每个模块单独定义版本号

5. 测试

// 每个模块可以独立测试
// network_module 测试
public class NetworkModuleTest {
    @Test
    public void testRequest() {
        // 测试网络请求
    }
}

面试常见问题

Q1: 什么是模块化?

答案: 模块化是将应用程序按照功能或职责拆分成多个独立的模块Module每个模块有明确的职责和接口。

Q2: 模块化和组件化的区别?

答案:

  • 模块化:粒度较细,按功能拆分,模块可以独立编译
  • 组件化:粒度较粗,按业务拆分,组件可以独立运行
  • 适用场景:模块化适合中大型项目,组件化适合大型项目、多团队协作

Q3: 如何划分模块?

答案:

  1. 按功能划分:网络模块、数据库模块、缓存模块等
  2. 按层次划分:表现层、领域层、数据层等
  3. 按业务划分:登录功能、首页功能、用户功能等
  4. 遵循单一职责、高内聚低耦合原则

Q4: 如何管理模块依赖?

答案:

  1. 依赖关系App Module → Feature Modules → Shared Modules → Base Module
  2. 避免循环依赖
  3. 统一版本管理
  4. 使用依赖注入

Q5: 如何实现模块间解耦?

答案:

  1. 接口隔离:定义接口,模块实现接口
  2. 依赖注入:使用 Dagger2 等框架
  3. 事件总线:使用 EventBus 等
  4. 服务发现:使用服务注册中心

Q6: 模块化的最佳实践?

答案:

  1. 模块职责清晰:单一职责原则
  2. 接口设计:职责单一,参数清晰
  3. 依赖管理:清晰、单向依赖
  4. 版本管理:统一管理版本号
  5. 测试:每个模块可以独立测试

总结

模块化是 Android 应用架构的重要方式,通过将应用拆分成多个独立模块,可以实现代码复用、易于维护、团队协作等优势。在实际项目中,需要合理划分模块、管理模块依赖、实现模块间解耦。


最后更新2024年