名词(术语)了解--架构-MVCMVVMMVP

名词(术语)了解–架构-MVC/MVVM/MVP

MVC

  1. 模型(Model)

    • 负责应用程序的数据逻辑和业务规则
    • 维护数据的状态和完整性
    • 与数据库等持久化层交互
    • 不依赖于视图和控制器
    • 当数据发生变化时,通知相关的视图进行更新
  2. 视图(View)

    • 负责数据的可视化展示
    • 将模型的数据呈现给用户
    • 接收用户的操作输入
    • 可以存在多个视图展示同一个模型的数据
    • 不直接处理业务逻辑
  3. 控制器(Controller)

    • 作为模型和视图之间的中介
    • 处理用户的交互请求
    • 更新模型的状态
    • 选择合适的视图进行展示
    • 协调整个应用程序的工作流程

MVC的工作流程:

  1. 用户通过视图界面进行操作
  2. 控制器接收用户的请求
  3. 控制器调用相应的模型进行数据处理
  4. 模型返回处理结果给控制器
  5. 控制器选择合适的视图进行展示
  6. 视图更新界面显示

MVC的优势:

  1. 关注点分离:每个组件负责特定的功能,使代码结构清晰
  2. 代码复用:模型可以被多个视图复用
  3. 并行开发:不同团队可以同时开发不同组件
  4. 维护性好:修改某一组件不会影响其他组件

实际应用示例:

# 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模式在现代框架中的应用:

  1. Web开发:

    • Django (Python):MTV模式(Model-Template-View,本质是MVC)
    • Spring MVC (Java)
    • Ruby on Rails:严格遵循MVC模式
  2. 移动开发:

    • iOS:Cocoa MVC
    • Android:Activity/Fragment可以看作Controller和View的组合
  3. 桌面应用:

    • JavaFX
    • Windows Forms

MVVM

  1. 模型(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() {
        // 保存数据到服务器
    }
}
  1. 视图(View)

    • 负责UI的展示和用户交互
    • 通过数据绑定与ViewModel进行通信
    • 不包含业务逻辑
    • 示例(Vue.js):

  1. 视图模型(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 = '保存失败';
        }
    }
}
  1. 数据绑定机制

    • 单向绑定:数据从ViewModel流向View
    • 双向绑定:View和ViewModel之间的数据自动同步
    • 示例(Vue.js的响应式系统):



  1. MVVM的主要特点:

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++
    }
}
  1. 实际应用场景:

a. Vue.js中的MVVM实现:




b. Angular中的MVVM实现:
// 组件类
@Component({
    selector: 'app-user',
    template: `
        
        

{{user.displayName}}

`
}) class UserComponent { user = { name: '', get displayName() { return `用户: ${this.name}`; } }; saveUser() { // 保存用户信息 } }
  1. MVVM的优势:

  • 更好的关注点分离
  • 更容易进行单元测试
  • 更好的代码复用
  • 更好的可维护性
  • 降低视图和业务逻辑的耦合
  1. 最佳实践:

  • 保持ViewModel的纯粹性
  • 避免在View中写业务逻辑
  • 使用计算属性处理数据转换
  • 合理使用数据绑定
  • 注意性能优化

MVP

  1. 模型(Model)

    • 负责数据和业务逻辑
    • 完全独立于UI层
    • 示例:
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('@');
    }
}
  1. 视图(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);
    }
}
  1. 展示者(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('发生错误');
        }
    }
}
  1. MVP的主要特点:

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 {
        // 导航到主页
    }
}
  1. 实际应用示例:

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 {
        // 隐藏加载指示器
    }
}
  1. MVP的优势:

  • 关注点分离更彻底
  • 视图可以轻易替换
  • 便于单元测试
  • 业务逻辑可复用
  • 维护性更好
  1. 最佳实践:

  • 保持View的简单性
  • Presenter不应该包含Android/iOS等平台特定代码
  • 使用接口定义View和Presenter的交互契约
  • 避免在Presenter中直接操作UI元素
  • 合理处理View的生命周期

你可能感兴趣的:(架构)