# Clean Architecture

## 目录
- [Clean Architecture概念](#clean-architecture概念)
- [分层架构](#分层架构)
- [依赖规则](#依赖规则)
- [领域层](#领域层)
- [数据层](#数据层)
- [表现层](#表现层)
- [Clean Architecture实现](#clean-architecture实现)
- [Clean Architecture最佳实践](#clean-architecture最佳实践)
- [面试常见问题](#面试常见问题)

---

## Clean Architecture概念

### 什么是 Clean Architecture？

Clean Architecture（整洁架构）是由 Robert C. Martin 提出的一种软件架构设计理念，强调：

1. **独立性**：框架、UI、数据库、外部服务都是可替换的
2. **可测试性**：业务逻辑可以独立测试
3. **独立性**：业务逻辑不依赖外部框架
4. **可维护性**：代码结构清晰，易于维护

### Clean Architecture 架构图

```
┌─────────────────────────────────────┐
│          Presentation Layer          │  ← 表现层（UI、ViewModel）
│  (Activities, Fragments, ViewModels) │
└──────────────┬──────────────────────┘
               │
┌──────────────▼──────────────────────┐
│           Domain Layer               │  ← 领域层（业务逻辑）
│  (Use Cases, Entities, Interfaces)  │
└──────────────┬──────────────────────┘
               │
┌──────────────▼──────────────────────┐
│            Data Layer               │  ← 数据层（Repository 实现）
│  (Repositories, Data Sources, API)  │
└─────────────────────────────────────┘
```

### Clean Architecture 核心原则

1. **依赖倒置**：依赖方向由外向内
2. **单一职责**：每个类只有一个职责
3. **开闭原则**：对扩展开放，对修改关闭
4. **接口隔离**：使用接口隔离依赖

---

## 分层架构

### 三层架构

#### 1. 表现层（Presentation Layer）

**职责：**
- 显示 UI
- 处理用户输入
- 调用 Use Case

**组件：**
- Activities
- Fragments
- ViewModels
- Adapters

#### 2. 领域层（Domain Layer）

**职责：**
- 业务逻辑
- 业务规则
- 实体定义

**组件：**
- Entities（实体）
- Use Cases（用例）
- Repository Interfaces（仓库接口）

#### 3. 数据层（Data Layer）

**职责：**
- 数据获取
- 数据存储
- Repository 实现

**组件：**
- Repository Implementations
- Data Sources（API、Database、Cache）
- Data Models

### 依赖方向

```
表现层 → 领域层 → 数据层
```

- 表现层依赖领域层
- 领域层不依赖表现层和数据层
- 数据层实现领域层的接口

---

## 依赖规则

### 依赖倒置原则

```java
// ✅ 正确：领域层定义接口，数据层实现接口
// Domain Layer
public interface UserRepository {
    Single<List<User>> getUsers();
}

// Data Layer
public class UserRepositoryImpl implements UserRepository {
    @Override
    public Single<List<User>> getUsers() {
        // 实现
    }
}

// ❌ 错误：领域层依赖数据层
// Domain Layer
public class UserUseCase {
    private UserRepositoryImpl repository; // 依赖具体实现
}
```

### 依赖方向

```
┌─────────────┐
│ Presentation │
└──────┬───────┘
       │ 依赖
       ↓
┌─────────────┐
│   Domain    │  ← 核心层，不依赖其他层
└──────┬───────┘
       │ 接口
       ↑ 实现
┌─────────────┐
│    Data     │
└─────────────┘
```

---

## 领域层

### Entity（实体）

```java
// Domain Layer: Entity
public class User {
    private String id;
    private String name;
    private String email;
    
    public User(String id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
    
    // Getters
    public String getId() { return id; }
    public String getName() { return name; }
    public String getEmail() { return email; }
    
    // 业务逻辑
    public boolean isValid() {
        return name != null && !name.isEmpty() 
            && email != null && email.contains("@");
    }
}
```

### Use Case（用例）

```java
// Domain Layer: Use Case
public class GetUsersUseCase {
    private UserRepository repository;
    
    public GetUsersUseCase(UserRepository repository) {
        this.repository = repository;
    }
    
    public Single<List<User>> execute() {
        return repository.getUsers()
            .map(users -> {
                // 业务逻辑处理
                return users.stream()
                    .filter(User::isValid)
                    .collect(Collectors.toList());
            });
    }
}

public class AddUserUseCase {
    private UserRepository repository;
    
    public AddUserUseCase(UserRepository repository) {
        this.repository = repository;
    }
    
    public Completable execute(User user) {
        if (!user.isValid()) {
            return Completable.error(new IllegalArgumentException("Invalid user"));
        }
        return repository.addUser(user);
    }
}
```

### Repository Interface（仓库接口）

```java
// Domain Layer: Repository Interface
public interface UserRepository {
    Single<List<User>> getUsers();
    Single<User> getUserById(String id);
    Completable addUser(User user);
    Completable updateUser(User user);
    Completable deleteUser(String id);
}
```

---

## 数据层

### Repository Implementation（仓库实现）

```java
// Data Layer: Repository Implementation
public class UserRepositoryImpl implements UserRepository {
    private UserRemoteDataSource remoteDataSource;
    private UserLocalDataSource localDataSource;
    
    public UserRepositoryImpl(
        UserRemoteDataSource remoteDataSource,
        UserLocalDataSource localDataSource
    ) {
        this.remoteDataSource = remoteDataSource;
        this.localDataSource = localDataSource;
    }
    
    @Override
    public Single<List<User>> getUsers() {
        return remoteDataSource.getUsers()
            .doOnSuccess(localDataSource::saveUsers)
            .onErrorResumeNext(localDataSource.getUsers());
    }
    
    @Override
    public Single<User> getUserById(String id) {
        return localDataSource.getUserById(id)
            .onErrorResumeNext(remoteDataSource.getUserById(id));
    }
    
    @Override
    public Completable addUser(User user) {
        return remoteDataSource.addUser(user)
            .andThen(localDataSource.saveUser(user));
    }
    
    @Override
    public Completable updateUser(User user) {
        return remoteDataSource.updateUser(user)
            .andThen(localDataSource.updateUser(user));
    }
    
    @Override
    public Completable deleteUser(String id) {
        return remoteDataSource.deleteUser(id)
            .andThen(localDataSource.deleteUser(id));
    }
}
```

### Data Source（数据源）

```java
// Data Layer: Remote Data Source
public class UserRemoteDataSource {
    private ApiService apiService;
    
    public UserRemoteDataSource(ApiService apiService) {
        this.apiService = apiService;
    }
    
    public Single<List<User>> getUsers() {
        return apiService.getUsers()
            .map(userResponses -> {
                return userResponses.stream()
                    .map(this::mapToUser)
                    .collect(Collectors.toList());
            });
    }
    
    private User mapToUser(UserResponse response) {
        return new User(
            response.getId(),
            response.getName(),
            response.getEmail()
        );
    }
}

// Data Layer: Local Data Source
public class UserLocalDataSource {
    private UserDao userDao;
    
    public UserLocalDataSource(UserDao userDao) {
        this.userDao = userDao;
    }
    
    public Single<List<User>> getUsers() {
        return userDao.getUsers()
            .map(userEntities -> {
                return userEntities.stream()
                    .map(this::mapToUser)
                    .collect(Collectors.toList());
            });
    }
    
    public void saveUsers(List<User> users) {
        List<UserEntity> entities = users.stream()
            .map(this::mapToEntity)
            .collect(Collectors.toList());
        userDao.insertUsers(entities);
    }
    
    private User mapToUser(UserEntity entity) {
        return new User(
            entity.getId(),
            entity.getName(),
            entity.getEmail()
        );
    }
    
    private UserEntity mapToEntity(User user) {
        UserEntity entity = new UserEntity();
        entity.setId(user.getId());
        entity.setName(user.getName());
        entity.setEmail(user.getEmail());
        return entity;
    }
}
```

---

## 表现层

### ViewModel

```java
// Presentation Layer: ViewModel
public class UserViewModel extends ViewModel {
    private GetUsersUseCase getUsersUseCase;
    private AddUserUseCase addUserUseCase;
    private MutableLiveData<List<User>> users = new MutableLiveData<>();
    private MutableLiveData<String> error = new MutableLiveData<>();
    private MutableLiveData<Boolean> loading = new MutableLiveData<>();
    
    public UserViewModel(
        GetUsersUseCase getUsersUseCase,
        AddUserUseCase addUserUseCase
    ) {
        this.getUsersUseCase = getUsersUseCase;
        this.addUserUseCase = addUserUseCase;
    }
    
    public LiveData<List<User>> getUsers() {
        return users;
    }
    
    public LiveData<String> getError() {
        return error;
    }
    
    public LiveData<Boolean> getLoading() {
        return loading;
    }
    
    public void loadUsers() {
        loading.setValue(true);
        getUsersUseCase.execute()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                userList -> {
                    loading.setValue(false);
                    users.setValue(userList);
                },
                throwable -> {
                    loading.setValue(false);
                    error.setValue(throwable.getMessage());
                }
            );
    }
    
    public void addUser(String name, String email) {
        loading.setValue(true);
        User user = new User(UUID.randomUUID().toString(), name, email);
        addUserUseCase.execute(user)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                () -> {
                    loading.setValue(false);
                    loadUsers();
                },
                throwable -> {
                    loading.setValue(false);
                    error.setValue(throwable.getMessage());
                }
            );
    }
}
```

### Activity/Fragment

```java
// Presentation Layer: Activity
public class UserActivity extends AppCompatActivity {
    private UserViewModel viewModel;
    private ActivityUserBinding binding;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_user);
        
        // 依赖注入
        UserRepository repository = new UserRepositoryImpl(
            new UserRemoteDataSource(createApiService()),
            new UserLocalDataSource(createUserDao())
        );
        
        GetUsersUseCase getUsersUseCase = new GetUsersUseCase(repository);
        AddUserUseCase addUserUseCase = new AddUserUseCase(repository);
        
        viewModel = ViewModelProviders.of(this, new ViewModelFactory(
            getUsersUseCase,
            addUserUseCase
        )).get(UserViewModel.class);
        
        binding.setViewModel(viewModel);
        binding.setLifecycleOwner(this);
        
        observeViewModel();
    }
    
    private void observeViewModel() {
        viewModel.getUsers().observe(this, users -> {
            adapter.updateUsers(users);
        });
        
        viewModel.getError().observe(this, error -> {
            Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
        });
    }
}
```

---

## Clean Architecture实现

### 项目结构

```
app/
├── presentation/           # 表现层
│   ├── ui/
│   │   ├── activities/
│   │   ├── fragments/
│   │   └── adapters/
│   └── viewmodels/
├── domain/                 # 领域层
│   ├── entities/
│   ├── usecases/
│   └── repositories/
└── data/                   # 数据层
    ├── repositories/
    ├── datasources/
    │   ├── remote/
    │   └── local/
    └── models/
```

### 依赖配置

```gradle
// app/build.gradle
dependencies {
    // 表现层依赖领域层
    implementation project(':domain')
    
    // 表现层依赖数据层（用于依赖注入）
    implementation project(':data')
}

// domain/build.gradle
dependencies {
    // 领域层不依赖其他层，只依赖 RxJava 等工具库
    implementation 'io.reactivex.rxjava2:rxjava:2.2.19'
}

// data/build.gradle
dependencies {
    // 数据层依赖领域层（实现接口）
    implementation project(':domain')
    
    // 数据层依赖第三方库
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'androidx.room:room-runtime:2.3.0'
}
```

---

## Clean Architecture最佳实践

### 1. 依赖倒置

```java
// ✅ 正确：领域层定义接口
// Domain Layer
public interface UserRepository {
    Single<List<User>> getUsers();
}

// Data Layer 实现接口
public class UserRepositoryImpl implements UserRepository {
    // 实现
}

// ❌ 错误：领域层依赖数据层
// Domain Layer
public class UserUseCase {
    private UserRepositoryImpl repository; // 依赖具体实现
}
```

### 2. 单一职责

```java
// ✅ 正确：每个类只有一个职责
public class GetUsersUseCase {
    public Single<List<User>> execute() {
        // 只负责获取用户列表
    }
}

public class AddUserUseCase {
    public Completable execute(User user) {
        // 只负责添加用户
    }
}

// ❌ 错误：一个类承担多个职责
public class UserUseCase {
    public void getUsers() { }
    public void addUser() { }
    public void updateUser() { }
    public void deleteUser() { }
}
```

### 3. 接口隔离

```java
// ✅ 正确：接口职责单一
public interface UserRepository {
    Single<List<User>> getUsers();
    Single<User> getUserById(String id);
}

// ❌ 错误：接口职责过多
public interface UserRepository {
    void getUsers();
    void addUser();
    void updateUser();
    void deleteUser();
    void uploadFile();
    void downloadFile();
}
```

### 4. 测试

```java
// 领域层可以独立测试
public class GetUsersUseCaseTest {
    @Test
    public void testExecute() {
        UserRepository mockRepository = mock(UserRepository.class);
        when(mockRepository.getUsers()).thenReturn(Single.just(users));
        
        GetUsersUseCase useCase = new GetUsersUseCase(mockRepository);
        useCase.execute()
            .test()
            .assertValue(users);
    }
}
```

---

## 面试常见问题

### Q1: 什么是 Clean Architecture？

**答案：**
Clean Architecture（整洁架构）是由 Robert C. Martin 提出的一种软件架构设计理念，强调：
1. 独立性：框架、UI、数据库都是可替换的
2. 可测试性：业务逻辑可以独立测试
3. 独立性：业务逻辑不依赖外部框架
4. 可维护性：代码结构清晰，易于维护

### Q2: Clean Architecture 的分层？

**答案：**
1. **表现层**：UI、ViewModel、Activities、Fragments
2. **领域层**：Entities、Use Cases、Repository Interfaces
3. **数据层**：Repository Implementations、Data Sources

### Q3: Clean Architecture 的依赖规则？

**答案：**
1. **依赖倒置**：领域层定义接口，数据层实现接口
2. **依赖方向**：表现层 → 领域层 → 数据层
3. **领域层独立**：领域层不依赖其他层

### Q4: Use Case 的作用？

**答案：**
Use Case（用例）封装了特定的业务逻辑，每个 Use Case 只负责一个业务功能，使业务逻辑清晰、可测试、可复用。

### Q5: Repository 模式的作用？

**答案：**
Repository 模式封装了数据访问逻辑，提供统一的数据访问接口，隐藏了数据来源（网络、数据库、缓存）的细节。

### Q6: Clean Architecture 的优势？

**答案：**
1. 可测试性：业务逻辑可以独立测试
2. 可维护性：代码结构清晰
3. 可扩展性：易于添加新功能
4. 独立性：不依赖外部框架

---

## 总结

Clean Architecture 是一种优秀的软件架构设计理念，通过分层架构和依赖倒置，实现了业务逻辑的独立性和可测试性。在实际项目中，需要合理划分层次、定义接口、实现依赖倒置。

---

*最后更新：2024年*
