# 模块化设计

## 目录
- [模块化概念](#模块化概念)
- [模块划分](#模块划分)
- [模块依赖管理](#模块依赖管理)
- [模块间解耦](#模块间解耦)
- [模块化实现](#模块化实现)
- [模块化最佳实践](#模块化最佳实践)
- [面试常见问题](#面试常见问题)

---

## 模块化概念

### 什么是模块化？

模块化是将应用程序按照功能或职责拆分成多个独立的模块（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 配置

```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. 避免循环依赖

```gradle
// ❌ 错误：循环依赖
// module_a 依赖 module_b
// module_b 依赖 module_a

// ✅ 正确：单向依赖
// module_a 依赖 module_b
// module_b 不依赖 module_a
```

### 4. 依赖版本管理

```gradle
// 项目 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. 接口隔离

```java
// 定义接口
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. 依赖注入

```java
// 使用 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. 事件总线

```java
// 使用 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. 服务发现

```java
// 服务注册中心
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. 模块配置

```gradle
// 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. 模块接口定义

```java
// 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. 模块初始化

```java
// 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. 模块职责清晰

```java
// ✅ 好的模块：职责单一
// 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. 接口设计

```java
// ✅ 好的接口：职责单一，参数清晰
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. 依赖管理

```gradle
// ✅ 好的依赖：清晰、单向
// feature_login → shared_network → base_common

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

### 4. 版本管理

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

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

### 5. 测试

```java
// 每个模块可以独立测试
// 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年*
