Hi,我是布兰妮甜 !在当今复杂的前端开发领域,如何组织代码结构一直是开发者面临的核心挑战。MVCMVVM作为两种经典的架构模式,为前端应用提供了清晰的责任划分和可维护的代码组织方案。本文将深入探讨这两种模式的原理、实现差异以及在实际项目中的应用场景,通过JavaScript代码示例展示它们的核心思想,帮助开发者理解如何根据项目需求选择合适的架构模式。


文章目录

    • 一、架构模式概述
    • 二、MVC架构模式
      • 2.1 MVC基本概念
      • 2.2 MVC数据流
      • 2.3 JavaScript实现示例
      • 2.4 MVC的优缺点
    • 三、MVVM架构模式
      • 3.1 MVVM基本概念
      • 3.2 MVVM数据流
      • 3.3 JavaScript实现示例(使用Vue.js)
      • 3.4 MVVM的优缺点
    • 四、MVC与MVVM的比较
    • 五、现代框架中的实现
      • 5.1 Vue.js - 典型的MVVM实现
      • 5.2 React - 类MVVM模式
      • 5.3 Angular - 完整的MVVM实现
    • 六、如何选择架构模式
    • 七、总结


一、架构模式概述

在软件开发中,架构模式决定了代码的组织方式,影响着应用程序的可维护性、可扩展性和可测试性。MVC(Model-View-Controller)和MVVM(Model-View-ViewModel)是两种广泛使用的架构模式,特别在前端开发中尤为重要。

二、MVC架构模式

2.1 MVC基本概念

  • Model(模型): 负责数据和业务逻辑
  • View(视图): 负责用户界面展示
  • Controller(控制器): 接收用户输入,协调Model和View

2.2 MVC数据流

  1. 用户与View交互(如点击按钮)
  2. View将用户操作传递给Controller
  3. Controller处理用户输入,可能需要更新Model
  4. Model将变更通知View
  5. View从Model获取最新数据并更新界面

2.3 JavaScript实现示例

// Model
class UserModel {constructor() {this.users = [];this.listeners = [];}addUser(user) {this.users.push(user);this.notifyListeners();}addListener(listener) {this.listeners.push(listener);}notifyListeners() {this.listeners.forEach(listener => listener(this.users));}
}// View
class UserView {constructor(controller) {this.controller = controller;this.userList = document.getElementById('user-list');this.addButton = document.getElementById('add-user-btn');this.nameInput = document.getElementById('user-name-input');this.addButton.addEventListener('click', () => {const name = this.nameInput.value;if (name) {this.controller.handleAddUser(name);this.nameInput.value = '';}});}update(users) {this.userList.innerHTML = users.map(user => `<li>${user}</li>`).join('');}
}// Controller
class UserController {constructor(model) {this.model = model;}handleAddUser(name) {this.model.addUser(name);}
}// 初始化
const model = new UserModel();
const controller = new UserController(model);
const view = new UserView(controller);model.addListener(users => view.update(users));

2.4 MVC的优缺点

优点:

  • 关注点分离,职责清晰
  • 可维护性强
  • 视图与模型解耦,可复用视图

缺点:

  • 对于复杂界面,控制器可能变得臃肿
  • 视图与模型间仍有直接或间接的依赖
  • 在现代富客户端应用中可能不够灵活

三、MVVM架构模式

3.1 MVVM基本概念

  • Model(模型): 负责数据和业务逻辑(与MVC相同)
  • View(视图): 用户界面展示(与MVC相同)
  • ViewModel(视图模型): 暴露数据和命令供View使用,充当View与Model之间的桥梁

3.2 MVVM数据流

  1. View通过数据绑定与ViewModel交互
  2. ViewModel从Model获取数据并暴露给View
  3. 用户操作触发ViewModel中的命令
  4. ViewModel处理命令,可能更新Model
  5. Model变更通过数据绑定自动反映到View

3.3 JavaScript实现示例(使用Vue.js)

// Model (与MVC示例相同)
class UserModel {constructor() {this.users = [];}addUser(user) {this.users.push(user);}getUsers() {return [...this.users];}
}// ViewModel (Vue实例)
const app = new Vue({el: '#app',data: {model: new UserModel(),newUserName: ''},computed: {users() {return this.model.getUsers();}},methods: {addUser() {if (this.newUserName) {this.model.addUser(this.newUserName);this.newUserName = '';}}}
});<!-- View (HTML) -->
<div id="app"><input v-model="newUserName" placeholder="Enter user name"><button @click="addUser">Add User</button><ul><li v-for="user in users" :key="user">{{ user }}</li></ul>
</div>

3.4 MVVM的优缺点

优点:

  • 数据绑定减少样板代码
  • 视图与模型完全解耦
  • 更易于单元测试
  • 适合数据驱动的UI

缺点:

  • 数据绑定可能带来性能问题(如果实现不当)
  • 调试复杂数据流可能困难
  • 学习曲线较陡

四、MVC与MVVM的比较

特性MVCMVVM
核心思想关注点分离数据驱动视图
通信方式Controller中介数据绑定
适合场景传统Web应用现代富客户端应用
复杂度中等较高
测试便利性需要模拟视图易于单元测试
典型框架Backbone.js, Spring MVCVue.js, Knockout.js

五、现代框架中的实现

5.1 Vue.js - 典型的MVVM实现

Vue.js 是一个典型的 MVVM 框架,其核心特性完美体现了 MVVM 模式的思想:

// Model
const userModel = {users: [],addUser(user) {this.users.push(user)},getUsers() {return [...this.users]}
}// ViewModel (Vue实例)
new Vue({el: '#app',data: {newUserName: '',users: []},created() {// 初始化数据this.users = userModel.getUsers()},methods: {addUser() {if (this.newUserName) {userModel.addUser(this.newUserName)this.users = userModel.getUsers()this.newUserName = ''}}}
})
<!-- View -->
<div id="app"><input v-model="newUserName" placeholder="输入用户名"><button @click="addUser">添加用户</button><ul><li v-for="user in users">{{ user }}</li></ul>
</div>

Vue.js 的 MVVM 实现特点:

  1. 数据绑定:通过 v-model 实现双向数据绑定
  2. 响应式系统:自动追踪依赖并更新视图
  3. 组件化:将 View 和 ViewModel 封装在组件中
  4. 指令系统v-forv-if 等指令简化视图逻辑

Vue 3 的 Composition API 进一步强化了 MVVM 模式:

import { ref, reactive } from 'vue'export default {setup() {const newUserName = ref('')const state = reactive({users: []})const addUser = () => {if (newUserName.value) {userModel.addUser(newUserName.value)state.users = userModel.getUsers()newUserName.value = ''}}return {newUserName,users: state.users,addUser}}
}

这种实现方式:

  • 更清晰地分离了关注点
  • 提供了更好的类型推断
  • 使逻辑复用更加容易
  • 保持了 MVVM 的核心思想

5.2 React - 类MVVM模式

虽然React官方不宣称使用MVVM,但其思想与MVVM相似:

// Model
const userModel = {users: [],addUser(user) {this.users.push(user);},getUsers() {return [...this.users];}
};// ViewModel组件
function UserList() {const [users, setUsers] = useState([]);const [newUser, setNewUser] = useState('');const handleAddUser = () => {if (newUser) {userModel.addUser(newUser);setUsers(userModel.getUsers());setNewUser('');}};return (<div><input value={newUser}onChange={(e) => setNewUser(e.target.value)}placeholder="Enter user name"/><button onClick={handleAddUser}>Add User</button><ul>{users.map((user, index) => (<li key={index}>{user}</li>))}</ul></div>);
}

5.3 Angular - 完整的MVVM实现

Angular明确采用MVVM模式:

// Model
export interface User {id: number;name: string;
}// ViewModel (Component)
@Component({selector: 'app-user-list',template: `<input [(ngModel)]="newUserName" placeholder="Enter user name"><button (click)="addUser()">Add User</button><ul><li *ngFor="let user of users">{{user.name}}</li></ul>`
})
export class UserListComponent {users: User[] = [];newUserName = '';private nextId = 1;addUser() {if (this.newUserName) {this.users.push({id: this.nextId++,name: this.newUserName});this.newUserName = '';}}
}

六、如何选择架构模式

  1. 项目复杂度:简单项目可能不需要MVVM的复杂性
  2. 团队熟悉度:团队对模式的熟悉程度影响开发效率
  3. 框架选择:所选框架可能倾向于某种模式
  4. 测试需求:MVVM通常更易于单元测试
  5. 数据绑定需求:数据密集型UI更适合MVVM

七、总结

MVC和MVVM都是优秀的架构模式,各有适用场景。理解它们的原理和区别有助于为项目选择合适的设计方案。随着前端技术的发展,现代框架往往融合了多种模式的优点,开发者应根据实际需求灵活应用这些架构思想。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/89979.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/89979.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/89979.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从小白到进阶:解锁linux与c语言高级编程知识点嵌入式开发的任督二脉(2)

【硬核揭秘】Linux与C高级编程&#xff1a;从入门到精通&#xff0c;你的全栈之路&#xff01; 第三部分&#xff1a;Shell脚本编程——自动化你的Linux世界&#xff0c;让效率飞起来&#xff01; 嘿&#xff0c;各位C语言的“卷王”们&#xff01; 在Linux的世界里&#xf…

锁和事务的关系

事务的4大特性(ACID) 原子性&#xff08;Atomicity&#xff09;&#xff1a;事务被视为一个单一的、不可分割的工作单元一致性&#xff08;Consistency&#xff09;&#xff1a;事务执行前后&#xff0c;数据库从一个一致状态转变为另一个一致状态&#xff0c;并且强制执行所有…

电动车信用免押小程序免押租赁小程序php方案

电动车信用免押租赁小程序&#xff0c;免押租小程序&#xff0c;信用免押接口申请、对接开发&#xff0c;可源码搭建&#xff0c;可二开或定制。开发语言后端php&#xff0c;前端uniapp。可二开定制 在线选择门店&#xff0c;选择车辆类型&#xff0c;选择租赁方式&#xff08…

机器学习在智能安防中的应用:视频监控与异常行为检测

随着人工智能技术的飞速发展&#xff0c;智能安防领域正经历着一场深刻的变革。智能安防通过整合先进的信息技术&#xff0c;如物联网&#xff08;IoT&#xff09;、大数据和机器学习&#xff0c;能够实现从传统的被动防御到主动预防的转变。机器学习技术在智能安防中的应用尤为…

MySQL中DROP、DELETE与TRUNCATE的深度解析

在MySQL数据库操作中&#xff0c;DROP、DELETE和TRUNCATE是三个常用的数据操作命令&#xff0c;它们都可以用于删除数据&#xff0c;但在功能、执行效率、事务处理以及对表结构的影响等方面存在显著差异。本文将从多个维度对这三个命令进行详细对比和解析&#xff0c;帮助读者更…

一条 SQL 语句的内部执行流程详解(MySQL为例)

当执行如下 SQL&#xff1a; SELECT * FROM users WHERE id 1;在数据库内部&#xff0c;其实会经历多个复杂且有序的阶段。以下是 MySQL&#xff08;InnoDB 引擎&#xff09;中 SQL 查询语句从发送到结果返回的完整执行流程。 客户端连接阶段 客户端&#xff08;如 JDBC、My…

超详细yolo8/11-detect目标检测全流程概述:配置环境、数据标注、训练、验证/预测、onnx部署(c++/python)详解

文章目录 一、配置环境二、数据标注三、模型训练四、验证预测五、onnx部署c 版python版本 一、配置环境 我的都是在Linux系统下&#xff0c;训练部署的&#xff1b;模型训练之前&#xff0c;需要配置好环境&#xff0c;Anaconda、显卡驱动、cuda、cudnn、pytorch等&#xff1b…

阿里云Flink:开启大数据实时处理新时代

走进阿里云 Flink 在大数据处理的广袤领域中&#xff0c;阿里云 Flink 犹如一颗璀璨的明星&#xff0c;占据着举足轻重的地位。随着数据量呈指数级增长&#xff0c;企业对数据处理的实时性、高效性和准确性提出了前所未有的挑战 。传统的数据处理方式逐渐难以满足这些严苛的需…

【Linux】基础开发工具(1)

1. 软件包管理器 1.1 什么是软件包 在Linux下安装软件, ⼀个常用的办法是下载到程序的源代码, 并进行编译, 得到可执行程序. 但是这样太麻烦了, 于是有些人把⼀些常⽤的软件提前编译好, 做成软件包(可以理解成windows上 的安装程序)放在⼀个服务器上, 通过包管理器可以很⽅便…

蓝桥杯51单片机设计

#超声波原理# ①超声波测距原理&#xff1a;声波反射原理 声波分类&#xff1a; 超声波测距原理 超声波频率越高&#xff0c;波长越短&#xff0c;反身性越强&#xff0c;衍射性越弱 ②超声波模块原理 发射原理 跳线帽 接收原理 问题&#xff1a; &#xff11;.超声波发射模块需…

【LeetCode 热题 100】240. 搜索二维矩阵 II——排除法

Problem: 240. 搜索二维矩阵 II 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 文章目录 整体思路完整代码时空复杂度时间复杂度&#xff1a;O(M N)空间复…

Android Input 系列专题【inputflinger事件的读取与分发】

Android输入系统在native中的核心工作就是&#xff0c;从Linux驱动设备节点中读取事件&#xff0c;然后将这个事件进行分发&#xff0c;这两项工作分别交给了InputReader和InputDispatcher来做。 他们的源码都属于native层inputflinger里面的一部分&#xff0c;如下架构&#…

【大模型LLM】GPU计算效率评估指标与优化方法:吞吐率

GPU计算效率评估指标与优化方法&#xff1a;吞吐率 一、核心效率指标二、大模型吞吐率&#xff08;Large Model Throughput&#xff09;三、关键性能瓶颈分析四、实际测量工具五、优化策略总结 一、核心效率指标 吞吐率&#xff08;Throughput&#xff09; 定义&#xff1a;单位…

Nestjs框架: 集成 Prisma

概述 在 NestJS 的官方文档中&#xff0c;有两处对数据库进行了介绍 第一处位于左侧“Techniques&#xff08;技术&#xff09;”部分下的“数据库”板块&#xff0c;中文文档里同样有这个位置。 Database 第二处是下面的“Recipes (秘籍)”板块&#xff0c;这里有多个部分都与…

CppCon 2018 学习:What Do We Mean When We Say Nothing At All?

提供的内容深入探讨了C编程中的一些关键概念&#xff0c;特别是如何编写清晰、易维护的代码&#xff0c;并展示了一些C17的新特性。我将对这些内容做中文的解释和总结。 1. 良好的代码设计原则 什么是“良好的代码”&#xff1f; 能工作&#xff1a;代码实现了预期功能。能在…

C语言中的输入输出函数:构建程序交互的基石

在C语言的世界里&#xff0c;输入输出&#xff08;I/O&#xff09;操作是程序与用户或外部数据源进行交互的基本方式。无论是从键盘接收用户输入&#xff0c;还是将处理结果显示到屏幕上&#xff0c;亦或是读写文件&#xff0c;都离不开C语言提供的输入输出函数。本文将深入探讨…

高速信号眼图

横轴体系时域的抖动大小&#xff1b;纵轴体现电压的噪声。 噪声越大&#xff0c;眼高越小。 抖动越大&#xff0c;眼宽越窄。 眼图的模板是定义好的最大jitter和噪声的模板范围。就是信号的不可触碰区域。信号波形不能够触碰到模板或者进行模板中。也就是眼图中的线轨迹要在眼…

VisualSVN Server 禁止的特殊符号 导致的。具体分析如下:错误提示解读

是由于 文件夹名称中包含了 VisualSVN Server 禁止的特殊符号 导致的。具体分析如下&#xff1a; 错误提示解读 错误信息明确说明&#xff1a; Folder name cannot contain following symbols < > : " / | and start or end by period. 即 文件夹名称不能包含以下…

再见,WebSecurityConfigurerAdapter!你好,SecurityFilterChain

对于许多经验丰富的 Spring开发者来说&#xff0c;WebSecurityConfigurerAdapter 是一个再熟悉不过的名字。在很长一段时间里&#xff0c;它几乎是所有 Spring Security 配置的起点和核心。然而&#xff0c;随着 Spring Boot 3.x 和 Spring Security 6.x 的普及&#xff0c;这个…

web前端面试-- MVC、MVP、MVVM 架构模式对比

MVC、MVP、MVVM 架构模式对比 基本概念 这三种都是用于分离用户界面(UI)与业务逻辑的架构模式&#xff0c;旨在提高代码的可维护性、可测试性和可扩展性。 1. MVC (Model-View-Controller) 核心结构&#xff1a; Model&#xff1a;数据模型和业务逻辑View&#xff1a;用户界面展…