马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
名词(术语)了解–架构-MVC/MVVM/MVP
MVC
- 模型(Model)
- 负责应用程序的数据逻辑和业务规则
- 维护数据的状态和完整性
- 与数据库等长期化层交互
- 不依赖于视图和控制器
- 当数据发生变化时,关照相关的视图进行更新
- 视图(View)
- 负责数据的可视化展示
- 将模型的数据出现给用户
- 吸取用户的操纵输入
- 可以存在多个视图展示同一个模型的数据
- 不直接处置处罚业务逻辑
- 控制器(Controller)
- 作为模型和视图之间的中介
- 处置处罚用户的交互请求
- 更新模型的状态
- 选择合适的视图进行展示
- 和谐整个应用程序的工作流程
MVC的工作流程:
- 用户通过视图界面进行操纵
- 控制器吸取用户的请求
- 控制器调用相应的模型进行数据处置处罚
- 模型返回处置处罚结果给控制器
- 控制器选择合适的视图进行展示
- 视图更新界面表现
MVC的上风:
- 关注点分离:每个组件负责特定的功能,使代码布局清楚
- 代码复用:模型可以被多个视图复用
- 并行开辟:差别团队可以同时开辟差别组件
- 维护性好:修改某一组件不会影响其他组件
实际应用示例:
- # Model
- class UserModel:
- def __init__(self):
- self.name = ""
- self.email = ""
-
- def save(self):
- # 保存用户数据到数据库
- pass
- # View
- class UserView:
- def show_user_details(self, name, email):
- print(f"User: {name}")
- print(f"Email: {email}")
-
- def get_user_input(self):
- name = input("Enter name: ")
- email = input("Enter email: ")
- return name, email
- # Controller
- class UserController:
- def __init__(self):
- self.model = UserModel()
- self.view = UserView()
-
- def create_user(self):
- name, email = self.view.get_user_input()
- self.model.name = name
- self.model.email = email
- self.model.save()
- self.view.show_user_details(name, email)
复制代码 MVC模式在现代框架中的应用:
- Web开辟:
- Django (Python):MTV模式(Model-Template-View,本质是MVC)
- Spring MVC (Java)
- Ruby on Rails:严格遵循MVC模式
- 移动开辟:
- iOS:Cocoa MVC
- Android:Activity/Fragment可以看作Controller和View的组合
- 桌面应用:
MVVM
- 模型(Model)
- 代表应用程序的数据和业务逻辑
- 包罗数据实体、数据访问层和业务规则
- 完全独立于UI层,不知道视图和视图模型的存在
- 示例:
- class UserModel {
- id: number;
- name: string;
- email: string;
- constructor(data: any) {
- this.id = data.id;
- this.name = data.name;
- this.email = data.email;
- }
- async save() {
- // 保存数据到服务器
- }
- }
复制代码
- 视图(View)
- 负责UI的展示和用户交互
- 通过数据绑定与ViewModel进行通讯
- 不包罗业务逻辑
- 示例(Vue.js):
- <template>
- <div>
- <input v-model="viewModel.userName" />
- <button @click="viewModel.saveUser">保存</button>
- <p>{{ viewModel.userStatus }}</p>
- </div>
- </template>
复制代码
- 视图模型(ViewModel)
- 作为视图的数据源和下令源
- 处置处罚视图的业务逻辑
- 将模型数据转换为视图可以使用的格式
- 管理视图状态
- 示例:
- class UserViewModel {
- private model: UserModel;
- public userName: string = '';
- public userStatus: string = '';
- constructor(model: UserModel) {
- this.model = model;
- this.userName = model.name;
- }
- async saveUser() {
- try {
- this.userStatus = '保存中...';
- await this.model.save();
- this.userStatus = '保存成功';
- } catch (error) {
- this.userStatus = '保存失败';
- }
- }
- }
复制代码
- 数据绑定机制
- 单向绑定:数据从ViewModel流向View
- 双向绑定:View和ViewModel之间的数据自动同步
- 示例(Vue.js的响应式系统):
- <script setup>
- import { ref, computed } from 'vue'
- const firstName = ref('')
- const lastName = ref('')
- // 计算属性示例
- const fullName = computed(() => {
- return firstName.value + ' ' + lastName.value
- })
- </script>
- <template>
- <input v-model="firstName" />
- <input v-model="lastName" />
- <p>全名: {{ fullName }}</p>
- </template>
复制代码 a. 数据绑定
- 自动同步数据和UI
- 淘汰手动DOM操纵
- 进步开辟效率
b. 下令模式
- // ViewModel中的命令
- class ViewModel {
- saveCommand = {
- execute: async () => {
- // 执行保存操作
- },
- canExecute: () => {
- // 判断是否可以执行
- return this.isValid;
- }
- }
- }
复制代码 c. 状态管理
- // Vue.js中的状态管理
- const store = {
- state: reactive({
- count: 0
- }),
- increment() {
- this.state.count++
- }
- }
复制代码 a. Vue.js中的MVVM实现:
- <!-- 组件示例 -->
- <template>
- <div>
- <input v-model="user.name" />
- <p>{{ user.displayName }}</p>
- <button @click="saveUser">保存</button>
- </div>
- </template>
- <script>
- export default {
- data() {
- return {
- user: {
- name: '',
- displayName: computed(() => `用户: ${this.user.name}`)
- }
- }
- },
- methods: {
- saveUser() {
- // 保存用户信息
- }
- }
- }
- </script>
复制代码 b. Angular中的MVVM实现:
- // 组件类
- @Component({
- selector: 'app-user',
- template: `
- <input [(ngModel)]="user.name" />
- <p>{{user.displayName}}</p>
- <button (click)="saveUser()">保存</button>
- `
- })
- class UserComponent {
- user = {
- name: '',
- get displayName() {
- return `用户: ${this.name}`;
- }
- };
- saveUser() {
- // 保存用户信息
- }
- }
复制代码
- 更好的关注点分离
- 更轻易进行单元测试
- 更好的代码复用
- 更好的可维护性
- 低落视图和业务逻辑的耦合
- 保持ViewModel的纯粹性
- 避免在View中写业务逻辑
- 使用计算属性处置处罚数据转换
- 合理使用数据绑定
- 注意性能优化
MVP
- class UserModel {
- private id: number;
- private name: string;
- private email: string;
- constructor(data: any) {
- this.id = data.id;
- this.name = data.name;
- this.email = data.email;
- }
- async save(): Promise<boolean> {
- // 保存数据到服务器
- return true;
- }
- validate(): boolean {
- return this.email.includes('@');
- }
- }
复制代码
- 视图(View)
- 定义视图接口
- 实现详细的UI展示
- 将用户操纵委托给Presenter
- 示例:
- // 视图接口
- interface IUserView {
- setName(name: string): void;
- setEmail(email: string): void;
- showError(message: string): void;
- showSuccess(message: string): void;
- }
- // 具体视图实现
- class UserView implements IUserView {
- private nameElement: HTMLInputElement;
- private emailElement: HTMLInputElement;
- private presenter: UserPresenter;
- constructor() {
- this.presenter = new UserPresenter(this);
- this.bindEvents();
- }
- private bindEvents() {
- document.getElementById('saveButton')
- .addEventListener('click', () => {
- this.presenter.onSaveClicked();
- });
- }
- setName(name: string): void {
- this.nameElement.value = name;
- }
- setEmail(email: string): void {
- this.emailElement.value = email;
- }
- showError(message: string): void {
- alert(message);
- }
- showSuccess(message: string): void {
- alert(message);
- }
- }
复制代码
- 展示者(Presenter)
- 处置处罚视图逻辑
- 操纵Model
- 更新View
- 示例:
- class UserPresenter {
- private view: IUserView;
- private model: UserModel;
- constructor(view: IUserView) {
- this.view = view;
- this.model = new UserModel({});
- }
- async onSaveClicked() {
- if (!this.model.validate()) {
- this.view.showError('数据验证失败');
- return;
- }
- try {
- const success = await this.model.save();
- if (success) {
- this.view.showSuccess('保存成功');
- } else {
- this.view.showError('保存失败');
- }
- } catch (error) {
- this.view.showError('发生错误');
- }
- }
- }
复制代码 a. 严格的分层
- // 视图层只负责UI展示
- interface IView {
- render(data: any): void;
- showLoading(): void;
- hideLoading(): void;
- }
- // Presenter层处理业务逻辑
- class Presenter {
- private view: IView;
- private model: Model;
- handleUserAction() {
- this.view.showLoading();
- this.model.process()
- .then(data => {
- this.view.render(data);
- this.view.hideLoading();
- });
- }
- }
复制代码 b. 视图接口化
- // 定义视图接口
- interface ILoginView {
- getUserName(): string;
- getPassword(): string;
- showError(message: string): void;
- navigateToHome(): void;
- }
- // 实现视图接口
- class LoginActivity implements ILoginView {
- private presenter: LoginPresenter;
- constructor() {
- this.presenter = new LoginPresenter(this);
- }
- getUserName(): string {
- return document.getElementById('username').value;
- }
- getPassword(): string {
- return document.getElementById('password').value;
- }
- showError(message: string): void {
- // 显示错误信息
- }
- navigateToHome(): void {
- // 导航到主页
- }
- }
复制代码 a. Android中的MVP实现:
- // View接口
- interface MainView {
- fun showProgress()
- fun hideProgress()
- fun setItems(items: List<String>)
- }
- // Presenter
- class MainPresenter(private val view: MainView) {
- private val model = MainModel()
- fun loadItems() {
- view.showProgress()
- model.getItems { items ->
- view.hideProgress()
- view.setItems(items)
- }
- }
- }
- // Activity实现View接口
- class MainActivity : AppCompatActivity(), MainView {
- private lateinit var presenter: MainPresenter
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- presenter = MainPresenter(this)
- presenter.loadItems()
- }
- override fun showProgress() {
- progressBar.visibility = View.VISIBLE
- }
- override fun hideProgress() {
- progressBar.visibility = View.GONE
- }
- override fun setItems(items: List<String>) {
- // 更新UI
- }
- }
复制代码 b. Web应用中的MVP实现:
- // View接口
- interface IProductView {
- displayProducts(products: Product[]): void;
- showLoadingIndicator(): void;
- hideLoadingIndicator(): void;
- }
- // Presenter
- class ProductPresenter {
- constructor(
- private view: IProductView,
- private model: ProductModel
- ) {}
- async loadProducts() {
- this.view.showLoadingIndicator();
- try {
- const products = await this.model.getProducts();
- this.view.displayProducts(products);
- } finally {
- this.view.hideLoadingIndicator();
- }
- }
- }
- // View实现
- class ProductPage implements IProductView {
- private presenter: ProductPresenter;
- constructor() {
- this.presenter = new ProductPresenter(this, new ProductModel());
- }
- displayProducts(products: Product[]): void {
- // 渲染产品列表
- }
- showLoadingIndicator(): void {
- // 显示加载指示器
- }
- hideLoadingIndicator(): void {
- // 隐藏加载指示器
- }
- }
复制代码
- 关注点分离更彻底
- 视图可以轻易替换
- 便于单元测试
- 业务逻辑可复用
- 维护性更好
- 保持View的简单性
- Presenter不应该包罗Android/iOS等平台特定代码
- 使用接口定义View和Presenter的交互左券
- 避免在Presenter中直接操纵UI元素
- 合理处置处罚View的生命周期
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |