MVC与MVP设计模式
MVC模式 (Model-View-Controller)
基本概念
MVC是一种将应用程序分为三个核心组件的设计模式:
-
Model(模型): 负责数据和业务逻辑
-
View(视图): 负责显示数据和用户界面
-
Controller(控制器): 处理用户输入并更新模型和视图
交互流程
┌─────────┐ ┌───────────┐ ┌──────┐
│ View │ ←→ │ Controller│ ←→ │ Model│
└─────────┘ └───────────┘ └──────┘↑ │└──────────────────────────────┘
-
用户与View交互(如点击按钮)
-
View将用户操作传递给Controller
-
Controller处理输入,可能需要更新Model
-
Model更新后通知View(通常通过观察者模式)
-
View从Model获取最新数据并更新显示
特点
-
View和Model之间存在直接通信
-
Controller相对较轻,主要作为中介
-
常用于Web框架如Spring MVC、Ruby on Rails等
MVP模式 (Model-View-Presenter)
基本概念
MVP是MVC的变体,主要区别在于:
-
Presenter取代了Controller
-
View和Model完全解耦
交互流程
┌──────┐ ┌───────────┐ ┌──────┐
│ View │ ←→ │ Presenter │ ←→ │ Model│
└──────┘ └───────────┘ └──────┘
-
用户与View交互
-
View将事件委托给Presenter
-
Presenter处理业务逻辑,可能需要更新Model
-
Model更新后通知Presenter(不是直接通知View)
-
Presenter从Model获取数据并更新View
特点
-
View和Model完全分离,通过Presenter通信
-
Presenter比Controller更重,包含更多展示逻辑
-
View通常是被动的,只负责显示
-
常用于桌面应用和Android开发
关键区别图示
MVC:
┌──────┐ ┌───────────┐ ┌──────┐
│ View │ ←───→ │Controller │ ←───→ │ Model│
└──────┘ └───────────┘ └──────┘↑ │└─────────────────────────────────┘MVP:
┌──────┐ ┌───────────┐ ┌──────┐
│ View │ ←───→ │Presenter │ ←───→ │ Model│
└──────┘ └───────────┘ └──────┘
(无直接View-Model通信)
优缺点比较
MVC优点
-
结构简单直接
-
开发速度快
-
适合小型到中型应用
MVC缺点
-
View和Model耦合
-
大型应用中Controller可能变得臃肿
-
单元测试较困难
MVP优点
-
更好的关注点分离
-
更易于单元测试
-
View和Model完全解耦
-
适合复杂UI逻辑
MVP缺点
-
需要更多样板代码
-
Presenter可能变得复杂
-
学习曲线略高
实际应用示例
MVC示例(Web应用)
// Model
public class User {private String name;// getters/setters
}// View (JSP)
<html><body>Hello ${user.name}</body></html>// Controller
@Controller
public class UserController {@GetMapping("/user")public String getUser(Model model) {model.addAttribute("user", new User("Alice"));return "userView";}
}
MVP示例(Android)
// Model
public class User {private String name;// getters/setters
}// View接口
public interface UserView {void showUserName(String name);
}// Presenter
public class UserPresenter {private UserView view;private User user;public UserPresenter(UserView view) {this.view = view;this.user = new User("Bob");}public void loadUser() {view.showUserName(user.getName());}
}// Activity实现View接口
public class UserActivity extends AppCompatActivity implements UserView {private UserPresenter presenter;protected void onCreate(Bundle b) {presenter = new UserPresenter(this);presenter.loadUser();}public void showUserName(String name) {textView.setText(name);}
}