找回密码
 立即注册
首页 业界区 业界 MVC、MVP、MVVM与DDD架构设计比较,不同语言源码实现 ...

MVC、MVP、MVVM与DDD架构设计比较,不同语言源码实现

铜坠匍 2025-6-6 14:51:50
MVC与MVP/MVVM/DDD架构对比,不同语言实现

MVC 分层架构设计概述

模型-视图-控制器(Model-View-Controller,简称 MVC)是一种经典软件架构设计,通过分层解耦,使得系统结构清晰和易于维护,具有良好的可扩展性。MVC 适用于需要清晰分离用户界面、业务逻辑和数据管理的应用场景。随着MVC的发展,还衍生出了MVP、MVVM以及领域驱动设计(DDD)等架构,这些都是为了让庞大的系统变得简单,易于人们理解。
1.png

MVC 结构图形示例

以Web后端开发为例
  1.                      用户请求  
  2.                        |  
  3.                        v
  4. +---------+       +-----------+      +-----------+
  5. |  View   |  <--- | Controller| ---> |   Model   |
  6. +---------+       +-----------+      +-----------+
  7.     ^                                      v
  8.     |            Model数据映射到View         |
  9.     ****--------------------------------****
复制代码
MVC各层职责


  • 视图层(View):处理用户界面展示和用户输入事件
  • 控制器层(Controller):接收用户请求,协调模型和视图
  • 模型层(Model):封装业务逻辑和数据结构
MVC是一种软件分层设计模式,目的是为了使得各层级解耦,使得代码更清晰和易于维护。常用来跟MVP、MVVM以及DDD分层架构对比,以下对这几种架构进行详细分析。MVC不同语言源码实现:https://github.com/microwind/design-patterns/tree/main/mvx/mvc
MVC 分层架构与 DDD 分层架构对比

MVC 以界面与数据分离为核心目标,强调快速开发;DDD 以领域模型驱动为核心思想,专注于复杂业务系统的可持续架构设计。
DDD 结构图形示例
  1. +--------------------+
  2. |     用户界面层       |
  3. |   User Interface   |
  4. |   含Controller/UI   |
  5. +--------------------+
  6.           |
  7.           v
  8. +--------------------+
  9. |      应用服务层      |
  10. |  Application Layer |
  11. |   含Service/DTO    |
  12. +--------------------+
  13.           |
  14.           v
  15. +--------------------+
  16. |       领域层        |
  17. |    Domain Layer    |
  18. |   含Model/Service  |
  19. +--------------------+
  20.           |
  21.           v
  22. +----------------------+
  23. |       基础设施层       |
  24. | Infrastructure Layer |
  25. | 含Repository/Message |
  26. +----------------------+
复制代码
DDD各语言源码:https://github.com/microwind/design-patterns/tree/main/domain-driven-design
MVC 分层架构与 DDD 分层架构特点

特性MVCDDD主要目标分离 UI、逻辑和数据解决复杂领域建模问题核心分层3 层(View、Controller、Model)4 层(UI、应用、领域、基础设施)适用场景Web 应用、前端交互密集型系统企业级复杂业务系统(如金融交易、供应链管理)开发效率快速原型开发,中小型项目友好需前期领域建模,适合长期演进的大型项目MVC与MVP、MVVM的分层架构对比

MVC与MVP总体上一致,只是在View与Model是否完全解耦上有差别。MVP通过接口隔离实现完全解耦,而MVC允许视图直接访问模型。MVC与MVVM的本质差异在于数据同步机制:MVVM通过双向绑定实现自动数据同步,MVC则依赖手动进行状态管理。
MVP(Model-View-Presenter)结构图形
  1. User Input  
  2.     |
  3.     v        由主持人代理View和Model交互
  4. +---------+      +-----------+       +-----------+
  5. |  View   | <--> | Presenter | <---> |   Model   |
  6. +---------+      +-----------+       +-----------+
  7. 1. MVP 主要用于前端开发,尤其是界面渲染,当一个界面需要针对多个视图数据进行渲染时,采用MVP比MVC更合适。
  8. 2. MVP 下 View 与 Model 隔离,View 中没有对应 Model 概念,数据由 Presenter 代为传递。
复制代码
MVP各语言源码:https://github.com/microwind/design-patterns/tree/main/mvx/mvp
MVVM(Model-View-ViewModel)
  1. User Input  
  2.     |
  3.     v         将View与Model双向数据绑定
  4. +---------+      +-----------+      +-----------+
  5. |  View   | ---> | ViewModel | <--> |   Model    |
  6. +---------+      +-----------+      +-----------+
  7.                    ^        |
  8.                    |        v
  9.           Data Binding(由Agent监听数据变化)
  10. 1. MVVM 从 View 触发,监听事件执行数据更新。
  11. 2. 通过代理监听数据变化,自动更新视图。
复制代码
MVVM各语言源码:https://github.com/microwind/design-patterns/tree/main/mvx/mvvm
MVC与MVP、MVVM的分层架构特点

模式控制流程描述View与Model耦合度组件角色MVC请求驱动模式
Controller 接收 View 请求 → 操作 Model → Model 直接通知 View 更新;View 主动监听 Model 事件。存在一定耦合,View 直接绑定 Model。Controller 处理逻辑;View 展示数据;Model 管理数据。MVP中介者模式:View 与 Presenter 双向交互:用户操作触发事件 → Presenter 调用 Model 更新 → Presenter 通知 View 更新。完全解耦,View 仅与 Presenter 交互,Model 不直接通知 View。Presenter 充当中介者;View 仅负责展示;Model 管理数据。MVVM响应式编程模式:利用数据绑定:View 与 ViewModel 双向绑定,ViewModel 操作 Model 后自动反映在 View 上。完全解耦,借助数据绑定技术实现 View 与 Model 之间的间接通信。ViewModel 充当桥梁;View 为声明式UI层;Model 纯数据结构。MVC是分层架构思想的先驱,后来MVP、MVVM、DDD等才流行开来,可以对比下几种分层代码,理解其中的变迁:https://github.com/microwind/design-patterns/tree/main/mvx
MVC 的应用场景


  • Web 应用程序(如电商网站、博客系统)
  • 前后端分离项目(RESTful API + 前端框架)
  • 桌面 GUI 应用(Java Swing、C# WinForms)
  • 移动端应用(Android Activity 结构)
MVC 的例子(C、Java、JavaScript、Go、Python等)

MVC最早从Smalltalk语言发展而来,后来经过Java、C++、.NET等将其发扬光大,除了传统的面向对象语言可以实现MVC模式,其他各种高级语言都可以实现MVC。需要注意的是MVC并非一种技术,而是一种理念。只要秉持这种分层思想,那么任何语言都可以实现MVC思想。
C 语言实现 MVC
  1. /* 视图层(View)*/
  2. // view.c
  3. #include <stdio.h>
  4. #include "controller.h"
  5. void display_order(Order order) {
  6.     printf("Order ID: %s\nCustomer: %s\nAmount: %.2f\n",
  7.            order.id, order.customer_name, order.amount);
  8. }
  9. /* 控制器层(Controller)*/
  10. // controller.c
  11. #include "controller.h"
  12. #include "repository.h"
  13. void create_order(Order order) {
  14.     save_order(order);
  15. }
  16. Order get_order(char* id) {
  17.     return find_order(id);
  18. }
  19. /* 模型层(Model)*/
  20. // order.h
  21. typedef struct {
  22.     char id[10];
  23.     char customer_name[50];
  24.     float amount;
  25. } Order;
  26. /* 数据访问层(Repository)*/
  27. // repository.c
  28. #include <string.h>
  29. #include "repository.h"
  30. static Order orders[100];
  31. static int count = 0;
  32. void save_order(Order order) {
  33.     orders[count++] = order;
  34. }
  35. Order find_order(char* id) {
  36.     for (int i = 0; i < count; i++) {
  37.         if (strcmp(orders[i].id, id) == 0) {
  38.             return orders[i];
  39.         }
  40.     }
  41.     Order empty = { "", "", 0 };
  42.     return empty;
  43. }
复制代码
Java 语言实现 MVC
  1. /* 视图层(View)*/
  2. // Thymeleaf 模板 (orders.html)
  3. <!DOCTYPE html>
  4. <html xmlns:th="http://www.thymeleaf.org">
  5. <body>
  6.     <h1>订单列表</h1>
  7.     <ul>
  8.         <li th:each="order : ${orders}">
  9.              -
  10.             
  11.         </li>
  12.     </ul>
  13. </body>
  14. </html>
  15. /* 控制器层(Controller)*/
  16. // OrderController.java
  17. @Controller
  18. @RequestMapping("/orders")
  19. public class OrderController {
  20.     private final OrderService service;
  21.     @Autowired
  22.     public OrderController(OrderService service) {
  23.         this.service = service;
  24.     }
  25.     @GetMapping
  26.     public String listOrders(Model model) {
  27.         model.addAttribute("orders", service.getAllOrders());
  28.         return "orders";
  29.     }
  30. }
  31. /* 模型层(Model)*/
  32. // Order.java
  33. @Entity
  34. public class Order {
  35.     @Id
  36.     @GeneratedValue(strategy = GenerationType.IDENTITY)
  37.     private Long id;
  38.     private String customerName;
  39.     private BigDecimal amount;
  40.     // Getters & Setters
  41. }
  42. /* 数据访问层(Repository)*/
  43. // OrderRepository.java
  44. public interface OrderRepository extends JpaRepository<Order, Long> {
  45.     List<Order> findByCustomerName(String name);
  46. }
复制代码
Go 语言实现 MVC
  1. /* 视图层(View)*/
  2. // view.go
  3. func RenderOrder(w http.ResponseWriter, order Order) {
  4.     fmt.Fprintf(w, "ID: %s\nCustomer: %s\nAmount: %.2f",
  5.         order.ID, order.CustomerName, order.Amount)
  6. }
  7. /* 控制器层(Controller)*/
  8. // controller.go
  9. func OrderHandler(w http.ResponseWriter, r *http.Request) {
  10.     id := r.URL.Query().Get("id")
  11.     order := repository.GetOrder(id)
  12.     RenderOrder(w, order)
  13. }
  14. /* 模型层(Model)*/
  15. // order.go
  16. type Order struct {
  17.     ID           string
  18.     CustomerName string
  19.     Amount       float64
  20. }
  21. /* 数据访问层(Repository)*/
  22. // repository.go
  23. var orders = make(map[string]Order)
  24. func GetOrder(id string) Order {
  25.     return orders[id]
  26. }
  27. func SaveOrder(order Order) {
  28.     orders[order.ID] = order
  29. }
复制代码
Python 语言实现 MVC(Flask)
  1. # 视图层(View)
  2. # templates/orders.html
  3. <html>
  4. <body>
  5.     <h1>Orders</h1>
  6.     <ul>
  7.         {% for order in orders %}
  8.             <li>{{ order.id }} - {{ order.customer_name }}</li>
  9.         {% endfor %}
  10.     </ul>
  11. </body>
  12. </html>
  13. # 控制器层(Controller)
  14. # app.py
  15. from flask import Flask, render_template
  16. from service import OrderService
  17. app = Flask(__name__)
  18. service = OrderService()
  19. @app.route('/orders')
  20. def list_orders():
  21.     orders = service.get_all_orders()
  22.     return render_template('orders.html', orders=orders)
  23. # 模型层(Model)
  24. # order.py
  25. class Order:
  26.     def __init__(self, id, customer_name, amount):
  27.         self.id = id
  28.         self.customer_name = customer_name
  29.         self.amount = amount
  30. # 数据访问层(Repository)
  31. # repository.py
  32. class OrderRepository:
  33.     def __init__(self):
  34.         self.orders = {}
  35.     def save(self, order):
  36.         self.orders[order.id] = order
  37.     def get_all(self):
  38.         return list(self.orders.values())
复制代码
JavaScript 实现 MVC(Express.js)
  1. /* 视图层(View)*/
  2. // views/orders.ejs
  3. <!DOCTYPE html>
  4. <html>
  5. <body>
  6.     <h1>Orders</h1>
  7.     <ul>
  8.         <% orders.forEach(order => { %>
  9.             <li><%= order.id %> - <%= order.customerName %></li>
  10.         <% }) %>
  11.     </ul>
  12. </body>
  13. </html>
  14. /* 控制器层(Controller)*/
  15. // routes/orderRoutes.js
  16. const express = require('express');
  17. const router = express.Router();
  18. const service = require('../services/orderService');
  19. router.get('/orders', async (req, res) => {
  20.     const orders = await service.getAllOrders();
  21.     res.render('orders', { orders });
  22. });
  23. /* 模型层(Model)*/
  24. // models/Order.js
  25. class Order {
  26.     constructor(id, customerName, amount) {
  27.         this.id = id;
  28.         this.customerName = customerName;
  29.         this.amount = amount;
  30.     }
  31. }
  32. /* 数据访问层(Repository)*/
  33. // repositories/orderRepository.js
  34. class OrderRepository {
  35.     constructor() {
  36.         this.db = new Map();
  37.     }
  38.     save(order) {
  39.         this.db.set(order.id, order);
  40.     }
  41.     getAll() {
  42.         return Array.from(this.db.values());
  43.     }
  44. }
复制代码
JavaScript 前端版 MVC

功能:点击按钮增减数值并更新视图。

  • 模型层:CounterModel 类封装数据和操作逻辑,包含数值和标题的修改方法。
  • 视图层:CounterView 类负责渲染界面,绑定模型数据,根据模型状态更新视图。
  • 控制层:CounterController 类作为中间层,绑定视图和模型,监听事件,实现数据和视图的更新。
  1. // Model 类:封装数据逻辑
  2. class CounterModel {
  3.     constructor() {
  4.         // 初始化数据
  5.         this.title = '点击更换标题';
  6.         this.num = 0;
  7.     }
  8.     // 标题操作:增加标题
  9.     changeTitle() {
  10.         this.title = '点击更换标题' + Math.floor(Math.random() * 100);
  11.     }
  12.     // 数据操作方法:增加数值
  13.     increment() {
  14.         this.num++;
  15.     }
  16.     // 数据操作方法:减少数值
  17.     decrement() {
  18.         this.num--;
  19.     }
  20. }
  21. // View 类:处理界面渲染
  22. class CounterView {
  23.     template(data = {}) {
  24.         return `
  25.         
  26.             <h3 >${data.title}</h3>
  27.             <button >-</button>
  28.             ${data.num}
  29.             <button >+</button>
  30.         
  31.         `;
  32.     }
  33.     constructor(model, container) {
  34.         this.model = model; // 绑定模型,这是跟MVP最大区别
  35.         this.$container = container;
  36.         this.init();
  37.     }
  38.     // 初始化DOM
  39.     init() {
  40.         this.$container.innerHTML = this.template(this.model);
  41.         this.$titleEl = this.$container.querySelector('.title');
  42.         this.$numEl = this.$container.querySelector('.num');
  43.         this.$incBtn = this.$container.querySelector('.inc-btn');
  44.         this.$decBtn = this.$container.querySelector('.dec-btn');
  45.     }
  46.     // 更新视图方法
  47.     render() {
  48.         // 可以根据数据是否有变化来确定要更新哪个字段
  49.         const data = this.model
  50.         this.$titleEl.textContent = data.title;
  51.         this.$numEl.textContent = data.num;
  52.     }
  53. }
  54. // Controller 类:处理用户输入
  55. class CounterController {
  56.     constructor(model, view) {
  57.         this.model = model;
  58.         this.view = view;
  59.         this.bindEvents();
  60.     }
  61.     // 绑定DOM事件
  62.     bindEvents() {
  63.         this.view.$titleEl.addEventListener('click', () => this.changeTitleHandle());
  64.         this.view.$incBtn.addEventListener('click', () => this.incrementHandle());
  65.         this.view.$decBtn.addEventListener('click', () => this.decrementHandle());
  66.     }
  67.     changeTitleHandle() {
  68.         this.model.changeTitle();
  69.         this.view.render(); // 直接更新视图,不必传递model
  70.     }
  71.     // 事件处理:增加操作
  72.     incrementHandle() {
  73.         this.model.increment();
  74.         this.view.render(); // 直接更新视图,不必传递model
  75.     }
  76.     // 事件处理:减少操作
  77.     decrementHandle() {
  78.         this.model.decrement();
  79.         this.view.render(); // 直接更新视图,不必传递model
  80.     }
  81. }
  82. // 初始化应用
  83. const appContainer = document.body;
  84. const model = new CounterModel();
  85. const view = new CounterView(model, appContainer);
  86. const controller = new CounterController(model, view);
复制代码
总结


  • MVC 适用于快速开发 Web 应用,强调职责分离。
  • MVP 适用于对视图和业务逻辑分离要求较高的场景,强调展示层对视图和模型的协调。
  • MVVM ​适用于复杂视图与模型交互的应用,利用数据绑定机制自动同步视图和模型的状态。
  • DDD 适用于复杂业务系统,强调领域建模。
  • 核心优势:代码可维护性强,团队协作效率高。
  • 选型建议:中小型项目优先考虑 MVC,复杂业务系统可结合 DDD。
最后


  • 要用 MVC 吗? 90% 的 Web 项目都适合 MVC 架构
  • 如何判断适用性? 如果需求变化主要集中在 UI 和流程的中小型项目,MVC 是最佳选择
  • 扩展建议:大型项目可在 MVC 基础上增加 Service 层和 DTO 对象,或者直接采用DDD架构
  • 更多设计与架构源码: https://github.com/microwind/design-patterns

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册