# MVC架构

## 目录
- [MVC模式介绍](#mvc模式介绍)
- [Android中的MVC](#android中的mvc)
- [MVC优缺点](#mvc优缺点)
- [MVC实现示例](#mvc实现示例)
- [MVC适用场景](#mvc适用场景)
- [面试常见问题](#面试常见问题)

---

## MVC模式介绍

### MVC 概念

MVC（Model-View-Controller）是一种软件架构模式，将应用程序分为三个核心组件：

- **Model（模型）**：数据和业务逻辑
- **View（视图）**：用户界面
- **Controller（控制器）**：处理用户输入，协调 Model 和 View

### MVC 架构图

```
┌─────────┐
│   View  │  ←─── 显示数据
└────┬────┘
     │ 用户交互
     ↓
┌─────────┐
│Controller│  ←─── 处理输入，更新 Model
└────┬────┘
     │ 更新
     ↓
┌─────────┐
│  Model │  ←─── 数据和业务逻辑
└─────────┘
```

### MVC 数据流

1. **用户操作 View** → Controller 接收输入
2. **Controller 处理** → 更新 Model
3. **Model 变化** → 通知 View 更新
4. **View 更新** → 显示最新数据

---

## Android中的MVC

### Android MVC 结构

在 Android 中，MVC 模式的实现：

- **Model**：数据模型、业务逻辑、数据访问层
- **View**：XML 布局文件、自定义 View
- **Controller**：Activity、Fragment

### Android MVC 示例

```java
// Model：数据模型
public class User {
    private String name;
    private String email;
    
    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }
    
    // Getters and Setters
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}

// Model：业务逻辑
public class UserModel {
    private List<User> users = new ArrayList<>();
    
    public void addUser(User user) {
        users.add(user);
    }
    
    public List<User> getUsers() {
        return users;
    }
    
    public User getUser(int position) {
        return users.get(position);
    }
}

// View：XML 布局
// activity_main.xml
<LinearLayout>
    <EditText
        android:id="@+id/etName"
        android:hint="Name" />
    <EditText
        android:id="@+id/etEmail"
        android:hint="Email" />
    <Button
        android:id="@+id/btnAdd"
        android:text="Add User" />
    <ListView
        android:id="@+id/lvUsers" />
</LinearLayout>

// Controller：Activity
public class MainActivity extends AppCompatActivity {
    private EditText etName, etEmail;
    private Button btnAdd;
    private ListView lvUsers;
    private UserModel userModel;
    private ArrayAdapter<User> adapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 初始化 View
        initViews();
        
        // 初始化 Model
        userModel = new UserModel();
        
        // 初始化 Adapter
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, userModel.getUsers());
        lvUsers.setAdapter(adapter);
        
        // 处理用户输入
        btnAdd.setOnClickListener(v -> {
            String name = etName.getText().toString();
            String email = etEmail.getText().toString();
            
            // Controller 更新 Model
            User user = new User(name, email);
            userModel.addUser(user);
            
            // Controller 更新 View
            adapter.notifyDataSetChanged();
            etName.setText("");
            etEmail.setText("");
        });
    }
    
    private void initViews() {
        etName = findViewById(R.id.etName);
        etEmail = findViewById(R.id.etEmail);
        btnAdd = findViewById(R.id.btnAdd);
        lvUsers = findViewById(R.id.lvUsers);
    }
}
```

---

## MVC优缺点

### 优点

1. **结构清晰**：职责分离，易于理解
2. **代码复用**：Model 和 View 可以复用
3. **易于测试**：Model 可以独立测试
4. **开发效率高**：适合小型项目快速开发

### 缺点

1. **Activity/Fragment 臃肿**：Controller 承担过多职责
2. **View 和 Model 耦合**：View 直接依赖 Model
3. **难以测试**：Activity/Fragment 难以进行单元测试
4. **维护困难**：随着项目增大，Controller 变得复杂

### Android MVC 的问题

```java
// ❌ 问题：Activity 承担了太多职责
public class MainActivity extends AppCompatActivity {
    // 1. 处理用户输入
    // 2. 更新 Model
    // 3. 更新 View
    // 4. 处理生命周期
    // 5. 处理配置变更
    // 6. 处理权限
    // ... 太多职责
}
```

---

## MVC实现示例

### 完整示例：用户列表

```java
// Model：用户数据模型
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 and Setters
    public String getId() { return id; }
    public String getName() { return name; }
    public String getEmail() { return email; }
}

// Model：用户业务逻辑
public class UserRepository {
    private List<User> users = new ArrayList<>();
    
    public void addUser(User user) {
        users.add(user);
    }
    
    public void removeUser(String id) {
        users.removeIf(user -> user.getId().equals(id));
    }
    
    public List<User> getAllUsers() {
        return new ArrayList<>(users);
    }
    
    public User getUserById(String id) {
        return users.stream()
            .filter(user -> user.getId().equals(id))
            .findFirst()
            .orElse(null);
    }
}

// View：布局文件
// activity_user_list.xml
<LinearLayout>
    <EditText android:id="@+id/etName" />
    <EditText android:id="@+id/etEmail" />
    <Button android:id="@+id/btnAdd" />
    <RecyclerView android:id="@+id/rvUsers" />
</LinearLayout>

// Controller：Activity
public class UserListActivity extends AppCompatActivity {
    private EditText etName, etEmail;
    private Button btnAdd;
    private RecyclerView rvUsers;
    private UserRepository userRepository;
    private UserAdapter adapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_list);
        
        initViews();
        initModel();
        setupRecyclerView();
        setupListeners();
    }
    
    private void initViews() {
        etName = findViewById(R.id.etName);
        etEmail = findViewById(R.id.etEmail);
        btnAdd = findViewById(R.id.btnAdd);
        rvUsers = findViewById(R.id.rvUsers);
    }
    
    private void initModel() {
        userRepository = new UserRepository();
    }
    
    private void setupRecyclerView() {
        adapter = new UserAdapter(userRepository.getAllUsers());
        rvUsers.setLayoutManager(new LinearLayoutManager(this));
        rvUsers.setAdapter(adapter);
    }
    
    private void setupListeners() {
        btnAdd.setOnClickListener(v -> {
            String name = etName.getText().toString();
            String email = etEmail.getText().toString();
            
            if (!name.isEmpty() && !email.isEmpty()) {
                // Controller 更新 Model
                User user = new User(UUID.randomUUID().toString(), name, email);
                userRepository.addUser(user);
                
                // Controller 更新 View
                adapter.updateUsers(userRepository.getAllUsers());
                etName.setText("");
                etEmail.setText("");
            }
        });
    }
}

// View：Adapter
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> {
    private List<User> users;
    
    public UserAdapter(List<User> users) {
        this.users = users;
    }
    
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_user, parent, false);
        return new ViewHolder(view);
    }
    
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        User user = users.get(position);
        holder.tvName.setText(user.getName());
        holder.tvEmail.setText(user.getEmail());
    }
    
    @Override
    public int getItemCount() {
        return users.size();
    }
    
    public void updateUsers(List<User> users) {
        this.users = users;
        notifyDataSetChanged();
    }
    
    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView tvName, tvEmail;
        
        ViewHolder(View itemView) {
            super(itemView);
            tvName = itemView.findViewById(R.id.tvName);
            tvEmail = itemView.findViewById(R.id.tvEmail);
        }
    }
}
```

---

## MVC适用场景

### 适合使用 MVC 的场景

1. **小型项目**：功能简单，快速开发
2. **原型开发**：快速验证想法
3. **学习项目**：理解架构模式
4. **简单 UI**：界面简单，交互少

### 不适合使用 MVC 的场景

1. **大型项目**：代码复杂，难以维护
2. **复杂业务逻辑**：Controller 会变得臃肿
3. **需要单元测试**：Activity 难以测试
4. **团队协作**：多人开发容易冲突

---

## 面试常见问题

### Q1: 什么是 MVC 模式？

**答案：**
MVC（Model-View-Controller）是一种软件架构模式，将应用程序分为三个核心组件：
- **Model**：数据和业务逻辑
- **View**：用户界面
- **Controller**：处理用户输入，协调 Model 和 View

### Q2: Android 中 MVC 的实现？

**答案：**
- **Model**：数据模型、业务逻辑、数据访问层
- **View**：XML 布局文件、自定义 View
- **Controller**：Activity、Fragment

### Q3: MVC 的优缺点？

**答案：**
- **优点**：结构清晰、代码复用、易于理解
- **缺点**：Activity 臃肿、View 和 Model 耦合、难以测试、维护困难

### Q4: MVC 和 MVP 的区别？

**答案：**
- **MVC**：View 可以直接访问 Model，Controller 处理输入和更新
- **MVP**：View 和 Model 完全解耦，Presenter 作为中间层，View 通过接口与 Presenter 通信

### Q5: 为什么 MVC 在 Android 中不常用？

**答案：**
1. Activity/Fragment 承担过多职责，变得臃肿
2. View 和 Model 耦合，难以测试和维护
3. 随着项目增大，Controller 变得复杂
4. 不适合大型项目和复杂业务逻辑

### Q6: MVC 适合什么场景？

**答案：**
- 适合：小型项目、原型开发、学习项目、简单 UI
- 不适合：大型项目、复杂业务逻辑、需要单元测试、团队协作

---

## 总结

MVC 是一种经典的架构模式，在 Android 中：
- **Model**：数据和业务逻辑
- **View**：XML 布局和自定义 View
- **Controller**：Activity 和 Fragment

虽然 MVC 结构简单，但在 Android 中容易导致 Activity 臃肿、难以测试等问题，因此在实际项目中，更多使用 MVP 或 MVVM 架构。

---

*最后更新：2024年*
