深入浅出:一文带你如何选择 MVC、MVVM、MVP 架构模式

854 阅读4分钟

前端架构模式详解:MVC、MVP、MVVM

前言

在软件开发和面试中,看着手中的MVCMVVMMVP三种经典的前端架构模式的法宝,你陷入了沉思。。。。。到底选哪个????,或者面试官问你:请介绍这三种架构模式是什么?有什么区别?这到底是个啥?本文将带你深入浅出地介绍这三种模式,看看如何选择。

MVC 架构模式

什么是 MVC?

MVC(Model-View-Controller)是最经典的架构模式,MVC最早由Trygve Reenskaug在1978年首次提出,后面的MVP、MVVM也都是基于MVC进行发展的,虽然经过了很多年的发展,但其核心仍然没有变化,所以先了解了MVC架构模式才能更容易弄懂MVP和MVVM。MVC将应用程序分为三个核心组件:

  • Model(模型层):用于处理数据和业务逻辑的类,主要负责网络请求,数据库处理以及I/O操作
  • View(视图层):用于负责用户界面显示,接收来自用户输入的数据和格式化输出,不包含业务逻辑,
  • Controller(控制层):用于处理用户请求,协调 Model 和 View

MVC三种模型的关系图:

graph TB
    %% 用户交互
    User[用户] --> View
    
    %% View层
    View[视图 View]
    View --> |1. 用户操作| Controller
    View --> |4. 更新显示| User
    
    %% Controller层
    Controller[控制器 Controller]
    Controller --> |2. 处理请求| Model
    Controller --> |3. 返回数据| View
    
    %% Model层
    Model[模型 Model]
    Model --> |数据操作| Database[(数据库)]
    Database --> |查询结果| Model
    
    %% 样式定义
    classDef viewClass fill:#e1f5fe,stroke:#01579b,stroke-width:2px
    classDef controllerClass fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
    classDef modelClass fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px
    classDef userClass fill:#fff3e0,stroke:#e65100,stroke-width:2px
    classDef dbClass fill:#fce4ec,stroke:#880e4f,stroke-width:2px
    
    class View viewClass
    class Controller controllerClass
    class Model modelClass
    class User userClass
    class Database dbClass

MVC数据流向图:

sequenceDiagram
    participant U as 用户
    participant V as View
    participant C as Controller
    participant M as Model
    participant D as 数据库
    
    U->>V: 1. 用户操作界面
    V->>C: 2. 发送请求到Controller
    C->>M: 3. 调用Model处理业务逻辑
    M->>D: 4. 查询/更新数据库
    D-->>M: 5. 返回数据结果
    M-->>C: 6. 返回处理结果
    C-->>V: 7. 返回数据给View
    V-->>U: 8. 更新界面显示

MVC 优缺点

优点:

  • 职责分离清晰,代码结构明确
  • 可维护性和可扩展性强
  • 适合团队协作开发
  • 测试相对容易

缺点:

  • View 和 Model 之间存在耦合
  • Controller 可能变得臃肿
  • 数据绑定需要手动处理

MVP 架构模式

什么是 MVP?

MVP(Model-View-Presenter)是在MVC基础上发展而来的架构模式,由Taligent公司在1990年代提出。MVP通过引入Presenter层来解决MVC中View和Model之间的耦合问题,使架构更加清晰。

  • Model(模型层):负责数据和业务逻辑,与MVC中的Model类似
  • View(视图层):只负责界面显示,不包含任何业务逻辑
  • Presenter(展示层):作为View和Model之间的中介,处理用户交互和业务逻辑

MVP架构关系图:

graph TB
    %% 用户交互
    User[用户] --> View
    
    %% View层
    View[视图 View]
    View --> |1. 用户操作| Presenter
    View --> |4. 更新显示| User
    
    %% Presenter层
    Presenter[展示器 Presenter]
    Presenter --> |2. 处理业务逻辑| Model
    Presenter --> |3. 更新View| View
    
    %% Model层
    Model[模型 Model]
    Model --> |数据操作| Database[(数据库)]
    Database --> |查询结果| Model
    
    %% 样式定义
    classDef viewClass fill:#e1f5fe,stroke:#01579b,stroke-width:2px
    classDef presenterClass fill:#fff8e1,stroke:#f57f17,stroke-width:2px
    classDef modelClass fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px
    classDef userClass fill:#fff3e0,stroke:#e65100,stroke-width:2px
    classDef dbClass fill:#fce4ec,stroke:#880e4f,stroke-width:2px
    
    class View viewClass
    class Presenter presenterClass
    class Model modelClass
    class User userClass
    class Database dbClass

MVP数据流向图:

sequenceDiagram
    participant U as 用户
    participant V as View
    participant P as Presenter
    participant M as Model
    participant D as 数据库
    
    U->>V: 1. 用户操作界面
    V->>P: 2. 通知Presenter用户操作
    P->>M: 3. 调用Model处理业务逻辑
    M->>D: 4. 查询/更新数据库
    D-->>M: 5. 返回数据结果
    M-->>P: 6. 返回处理结果
    P->>V: 7. 更新View显示
    V-->>U: 8. 界面更新完成

MVP 优缺点

优点:

  • View 和 Model 完全解耦
  • 业务逻辑集中在 Presenter 中,便于测试
  • 代码结构清晰,职责分离明确
  • 适合复杂的企业级应用

缺点:

  • 需要编写更多的接口代码
  • Presenter 可能变得复杂
  • 数据绑定仍需手动处理

MVVM 架构模式

什么是 MVVM?

MVVM(Model-View-ViewModel)是由微软在2005年提出的架构模式,主要用于WPF应用程序开发。MVVM通过数据绑定机制实现了View和Model的自动同步,大大简化了开发工作。

  • Model(模型层):负责数据和业务逻辑,与MVC/MVP中的Model类似
  • View(视图层):只负责界面显示,通过数据绑定与ViewModel交互
  • ViewModel(视图模型层):作为View的数据模型,包含View的显示逻辑和状态

MVVM架构关系图:

graph TB
    %% 用户交互
    User[用户] --> View
    
    %% View层
    View[视图 View]
    View -.->|数据绑定| ViewModel
    View --> |1. 用户操作| ViewModel
    View --> |4. 自动更新| User
    
    %% ViewModel层
    ViewModel[视图模型 ViewModel]
    ViewModel --> |2. 处理业务逻辑| Model
    ViewModel -.->|数据绑定| View
    
    %% Model层
    Model[模型 Model]
    Model --> |数据操作| Database[(数据库)]
    Database --> |查询结果| Model
    
    %% 样式定义
    classDef viewClass fill:#e1f5fe,stroke:#01579b,stroke-width:2px
    classDef viewModelClass fill:#f1f8e9,stroke:#33691e,stroke-width:2px
    classDef modelClass fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px
    classDef userClass fill:#fff3e0,stroke:#e65100,stroke-width:2px
    classDef dbClass fill:#fce4ec,stroke:#880e4f,stroke-width:2px
    
    class View viewClass
    class ViewModel viewModelClass
    class Model modelClass
    class User userClass
    class Database dbClass

MVVM数据流向图:

sequenceDiagram
    participant U as 用户
    participant V as View
    participant VM as ViewModel
    participant M as Model
    participant D as 数据库
    
    U->>V: 1. 用户操作界面
    V->>VM: 2. 通过数据绑定自动更新ViewModel
    VM->>M: 3. 调用Model处理业务逻辑
    M->>D: 4. 查询/更新数据库
    D-->>M: 5. 返回数据结果
    M-->>VM: 6. 更新ViewModel数据
    VM-->>V: 7. 通过数据绑定自动更新View
    V-->>U: 8. 界面自动更新完成

MVVM 优缺点

优点:

  • 数据绑定自动化,减少样板代码
  • View 和 Model 完全解耦
  • 代码简洁,开发效率高
  • 适合现代前端框架(Vue、Angular、React)

缺点:

  • 学习成本较高
  • 调试相对困难
  • 过度使用可能导致性能问题

三种架构模式对比

演进总结

特性MVCMVPMVVM
数据绑定手动手动自动
View 职责显示+输入显示+输入纯显示
测试难度中等容易容易
代码量中等
学习成本中等
适用场景传统 Web企业应用现代 SPA

架构演进图

graph LR
    A[MVC<br/>1978年] --> B[MVP<br/>1990年代]
    B --> C[MVVM<br/>2005年]
    C --> D[现代框架<br/>组件化]
    
    style A fill:#e1f5fe
    style B fill:#fff8e1
    style C fill:#f1f8e9
    style D fill:#fce4ec

实际应用示例

MVC 示例(传统Web应用)

// Model
class UserModel {
    async getUser(id) {
        const response = await fetch(`/api/users/${id}`);
        return response.json();
    }
}

// View
class UserView {
    displayUser(user) {
        document.getElementById('userName').textContent = user.name;
        document.getElementById('userEmail').textContent = user.email;
    }
}

// Controller
class UserController {
    constructor(model, view) {
        this.model = model;
        this.view = view;
    }
    
    async loadUser(id) {
        const user = await this.model.getUser(id);
        this.view.displayUser(user);
    }
}

MVP 示例

// Model
class UserModel {
    async getUser(id) {
        const response = await fetch(`/api/users/${id}`);
        return response.json();
    }
}

// View Interface
class IUserView {
    displayUser(user) {}
    showLoading() {}
    hideLoading() {}
}

// Presenter
class UserPresenter {
    constructor(model, view) {
        this.model = model;
        this.view = view;
    }
    
    async loadUser(id) {
        this.view.showLoading();
        try {
            const user = await this.model.getUser(id);
            this.view.displayUser(user);
        } finally {
            this.view.hideLoading();
        }
    }
}

MVVM 示例(Vue.js)

// Model
class UserModel {
    async getUser(id) {
        const response = await fetch(`/api/users/${id}`);
        return response.json();
    }
}

// ViewModel
class UserViewModel {
    constructor() {
        this.user = reactive({
            name: '',
            email: '',
            loading: false
        });
    }
    
    async loadUser(id) {
        this.user.loading = true;
        try {
            const userData = await new UserModel().getUser(id);
            this.user.name = userData.name;
            this.user.email = userData.email;
        } finally {
            this.user.loading = false;
        }
    }
}

// View (Vue Template)
/*
<template>
  <div>
    <div v-if="user.loading">加载中...</div>
    <div v-else>
      <h2>{{ user.name }}</h2>
      <p>{{ user.email }}</p>
    </div>
  </div>
</template>
*/

那我们如何选择?

我觉得我们倒不如去先好好了解他们,不用过于纠结使用什么架构模式或框架,只要适应业务场景和开发需要,选择合适的才是最佳方案,MVC、MVP、MVVM 是三种经典的软件架构模式,每种都有其适用场景和优缺点。无论选择哪种架构模式,核心目标都是提高代码的可维护性、可扩展性和可测试性。在实际项目中,我们往往会根据具体需求和团队情况,选择最适合的架构模式或进行适当的调整。