这三种都是分层架构设计模式,核心目标是解耦代码、提高可维护性和可测试性,在 C# 开发(尤其是桌面 / Web 应用)中应用广泛。下面从「定义 + 核心角色 + C# 示例 + 适用场景」逐一讲解。
一、MVC(Model-View-Controller)
1. 核心概念
- Model:数据模型(业务逻辑、数据实体),不依赖任何层。
- View:视图(UI 界面),展示数据,接收用户输入,依赖 Model。
- Controller:控制器,处理用户请求,协调 Model 和 View(比如接收 View 的输入,调用 Model 处理数据,再更新 View)。
- 核心流程:用户操作 → Controller 接收 → 调用 Model 处理数据 → Controller 传递数据给 View → View 展示。
- 特点:View 和 Controller 双向交互,Controller 直接控制 View 的更新。
2. C# MVC 简单示例(ASP.NET MVC 场景)
// 1. Model(数据模型)
public class UserModel
{
public int Id { get; set; }
public string Name { get; set; }
// 模拟业务逻辑
public UserModel GetUserById(int id)
{
return new UserModel { Id = id, Name = "张三" };
}
}
// 2. Controller(控制器,ASP.NET MVC 中继承 Controller 基类)
public class UserController : Controller
{
// 处理用户请求(比如访问 /User/Detail/1)
public ActionResult Detail(int id)
{
// 调用 Model 获取数据
var userModel = new UserModel();
var user = userModel.GetUserById(id);
// 将数据传递给 View
return View(user);
}
}
// 3. View(视图,Razor 页面 /Views/User/Detail.cshtml)
@model UserModel
<h1>用户详情</h1>
<p>ID:@Model.Id</p>
<p>姓名:@Model.Name</p>
3. 适用场景
- ASP.NET MVC(Web 应用)、WinForm 基础场景。
- 适合简单应用,开发速度快,但 View 和 Controller 耦合度略高。
二、MVP(Model-View-Presenter)
1. 核心概念
MVC 的改进版,核心是解耦 View 和 Model,引入 Presenter 作为中间层:
- Model:和 MVC 一致(数据 / 业务逻辑)。
- View :纯展示层,不包含任何业务逻辑,仅暴露接口给 Presenter 调用(比如
ShowUser(UserModel))。 - Presenter:主持人,持有 View 和 Model 的引用,处理所有业务逻辑,是核心层(View 的输入交给 Presenter,Presenter 调用 Model 后,通过 View 接口更新界面)。
- 核心流程:用户操作 → View 通知 Presenter → Presenter 调用 Model → Presenter 通过 View 接口更新 View。
- 特点:View 完全被动,Presenter 主导,View 和 Model 完全解耦,可测试性更强。
2. C# MVP 简单示例(WinForm 场景)
// 1. Model
public class UserModel
{
public int Id { get; set; }
public string Name { get; set; }
public UserModel GetUser(int id)
{
return new UserModel { Id = id, Name = "李四" };
}
}
// 2. View 接口(解耦 Presenter 和具体 View)
public interface IUserView
{
int UserId { get; set; } // 接收用户输入的 ID
void ShowUserInfo(string name); // 展示用户名称
}
// 3. Presenter
public class UserPresenter
{
private readonly IUserView _view;
private readonly UserModel _model;
public UserPresenter(IUserView view)
{
_view = view;
_model = new UserModel();
}
// 处理「查询用户」逻辑
public void LoadUser()
{
var user = _model.GetUser(_view.UserId);
_view.ShowUserInfo(user.Name); // 通过接口更新 View
}
}
// 4. 具体 View(WinForm 窗体)
public partial class UserForm : Form, IUserView
{
private readonly UserPresenter _presenter;
public UserForm()
{
InitializeComponent();
_presenter = new UserPresenter(this);
// 按钮点击事件绑定
btnQuery.Click += (s, e) => _presenter.LoadUser();
}
// 实现 IUserView 接口
public int UserId
{
get => int.Parse(txtId.Text);
set => txtId.Text = value.ToString();
}
public void ShowUserInfo(string name)
{
lblName.Text = name; // 更新界面控件
}
}
3. 适用场景
- WinForm/WPF 桌面应用(早期)、对测试性要求较高的中小型应用。
- 缺点:Presenter 可能会变得臃肿(需手动处理大量 View 接口)。
三、MVVM(Model-View-ViewModel)
1. 核心概念
MVP 的进阶版,核心是数据绑定(Data Binding),消除 Presenter 手动更新 View 的冗余代码:
- Model:和前两者一致(数据 / 业务逻辑)。
- View :视图(UI),通过数据绑定和 ViewModel 关联,无需手动更新,支持双向绑定(View 输入自动同步到 ViewModel,ViewModel 数据变化自动更新 View)。
- ViewModel :视图模型,封装 View 的逻辑和数据,实现
INotifyPropertyChanged(通知 View 数据变化),是 View 的「抽象」,不依赖具体 View。 - 核心流程:用户操作 → View 绑定的 ViewModel 接收数据 → ViewModel 调用 Model → ViewModel 触发属性变更通知 → View 自动更新。
- 特点:数据驱动,无需手动更新 View,View 和 ViewModel 解耦,可测试性最高。
2. C# MVVM 简单示例(WPF 场景)
// 1. 基础类:实现属性变更通知(MVVM 核心)
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
// 2. Model
public class UserModel
{
public int Id { get; set; }
public string Name { get; set; }
public UserModel GetUser(int id)
{
return new UserModel { Id = id, Name = "王五" };
}
}
// 3. ViewModel
public class UserViewModel : ObservableObject
{
private readonly UserModel _model;
private int _userId;
private string _userName;
// 绑定到 View 的属性(用户输入的 ID)
public int UserId
{
get => _userId;
set
{
_userId = value;
OnPropertyChanged(); // 通知 View 数据变化
}
}
// 绑定到 View 的属性(展示的用户名)
public string UserName
{
get => _userName;
set
{
_userName = value;
OnPropertyChanged(); // 通知 View 数据变化
}
}
// 绑定到 View 按钮的命令
public ICommand LoadUserCommand { get; }
public UserViewModel()
{
_model = new UserModel();
// 初始化命令(RelayCommand 是 WPF 中常用的命令实现)
LoadUserCommand = new RelayCommand(LoadUser);
}
private void LoadUser()
{
var user = _model.GetUser(UserId);
UserName = user.Name; // 自动通知 View 更新
}
}
// 辅助:RelayCommand 实现(WPF 命令接口)
public class RelayCommand : ICommand
{
private readonly Action _execute;
public event EventHandler? CanExecuteChanged;
public RelayCommand(Action execute) => _execute = execute;
public bool CanExecute(object? parameter) => true;
public void Execute(object? parameter) => _execute();
}
// 4. View(WPF XAML,数据绑定)
<Window x:Class="MVVMDemo.UserWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:MVVMDemo"
Title="用户查询" Height="200" Width="300">
<!-- 设置 DataContext 为 ViewModel -->
<Window.DataContext>
<vm:UserViewModel />
</Window.DataContext>
<StackPanel Margin="20">
<!-- 双向绑定 UserId:View 输入同步到 ViewModel -->
<TextBox Text="{Binding UserId, Mode=TwoWay}" PlaceholderText="输入用户ID"/>
<!-- 绑定命令:点击按钮触发 ViewModel 的 LoadUser 方法 -->
<Button Content="查询" Command="{Binding LoadUserCommand}" Margin="0,10"/>
<!-- 绑定 UserName:ViewModel 变化自动更新 View -->
<TextBlock Text="{Binding UserName}" FontSize="16"/>
</StackPanel>
</Window>
3. 适用场景
- WPF/MAUI/Blazor(现代 C# 界面框架)、复杂交互的桌面 / 跨平台应用。
- 优点:数据驱动,代码量少,可测试性和可维护性最优;缺点:学习成本略高(需理解数据绑定、命令等概念)。
四、三者核心对比
| 特性 | MVC | MVP | MVVM |
|---|---|---|---|
| 核心解耦 | View-Controller 耦合 | View-Presenter 接口解耦 | View-ViewModel 数据绑定解耦 |
| 交互方式 | Controller 直接更新 View | Presenter 调用 View 接口 | 数据绑定自动更新 |
| 测试性 | 中等 | 较高 | 最高 |
| 适用框架 | ASP.NET MVC | WinForm(早期) | WPF/MAUI/Blazor |
| 代码冗余 | 少 | 中(手动写接口) | 少(数据绑定) |
总结
- MVC :最基础,Controller 主导,适合简单 Web 应用(如 ASP.NET MVC),开发快但耦合略高。
- MVP:解耦 View 和 Model,Presenter 手动控制 View,适合早期桌面应用,测试性优于 MVC。
- MVVM:数据驱动核心,依赖数据绑定,是现代 C# 界面开发(WPF/MAUI)的首选,解耦和可维护性最优。
核心选择原则:简单 Web 用 MVC,现代桌面 / 跨平台用 MVVM,MVP 仅作为过渡或老项目维护场景使用。