MVP架构模式(一种衍生于经典MVC架构的界面设计模式,旨在优化代码组织结构并提高可测试性)(Model层、View层、Presenter层)(软件设计模式、MVVW)

文章目录

20220109(原)

在这里插入图片描述

  • View: 是显示数据(model)并且将用户指令(events)传送到presenter以便作用于那些数据的一个接口。View通常含有Presenter的引用。在Android开发中通常将Activity或者Fragment作为View层。
  • Model: 对于Model层也是数据层。它区别于MVC架构中的Model,在这里不仅仅只是数据模型。在MVP架构中Model它负责对数据的存取操作,例如对数据库的读写,网络的数据的请求等。
  • Presenter:对于Presenter层他是连接View层与Model层的桥梁并对业务逻辑进行处理。在MVP架构中Model与View无法直接进行交互。所以在Presenter层它会从Model层获得所需要的数据,进行一些适当的处理后交由View层进行显示。这样通过Presenter将View与Model进行隔离,使得View和Model之间不存在耦合,同时也将业务逻辑从View中抽离。

参考文章:MVP架构模式详解

20250321 MVP模式全解析

背景概述

MVP(Model-View-Presenter)模式是一种衍生于经典MVC架构的界面设计模式,旨在优化代码组织结构并提高可测试性。该模式通过明确划分职责边界,使得界面逻辑与业务逻辑彻底分离,为复杂应用开发提供了强大支撑。

MVP核心架构

Model层(Model层负责数据管理与业务逻辑)

- 封装核心业务规则和数据状态
- 独立于UI层,不感知界面变化
- 提供数据访问接口与数据操作方法
- 通常包含实体类、服务类和数据源

View层(View层专注于界面展示)

- 被动接收指令,展示数据
- 将用户交互事件委托给Presenter处理
- 不包含业务逻辑,仅负责UI呈现
- 通常由Activity、Fragment或自定义View实现

Presenter层(Presenter层作为核心协调者)

- 连接Model与View的桥梁
- 处理View层传递的用户事件
- 从Model获取数据并格式化后交给View显示
- 包含应用逻辑但不直接操作UI元素

MVP与MVC对比(MVC:Model、View、Controller)

结构差异

- MVC模式中,Controller作为中央协调者,同时View可直接访问Model
MVC: View ←→ Controller ←→ Model
      ↑______________________|
- MVP模式中,Presenter完全隔离View和Model:
MVP: View ←→ Presenter ←→ Model

交互方式

- MVC:View可直接观察Model变化
- MVP:View与Model完全解耦,所有交互通过Presenter中转

测试性(MVP显著提高了测试覆盖率)

具体原因如下:

- Presenter不依赖具体UI实现
- 可通过模拟View进行单元测试
- 业务逻辑集中在Presenter,便于编写测试用例

MVP实现示例

定义契约接口

public interface TaskContract {
    interface View {
        void showTasks(List<Task> tasks);
        void showTaskDetails(Task task);
        void showLoadingError();
        void showLoading(boolean active);
    }

    interface Presenter {
        void loadTasks();
        void openTaskDetails(Task task);
        void addNewTask();
        void start();
    }
}

Model实现

public class TaskRepository {
    private TaskDataSource localDataSource;
    private TaskDataSource remoteDataSource;
    
    public void getTasks(LoadTasksCallback callback) {
        // 实现数据获取逻辑
        // ...
    }
    
    public void saveTask(Task task) {
        // 实现数据保存逻辑
        // ...
    }
}

Presenter实现

public class TaskPresenter implements TaskContract.Presenter {
    private final TaskRepository repository;
    private final TaskContract.View view;
    
    public TaskPresenter(TaskRepository repository, TaskContract.View view) {
        this.repository = repository;
        this.view = view;
    }
    
    @Override
    public void loadTasks() {
        view.showLoading(true);
        repository.getTasks(new LoadTasksCallback() {
            @Override
            public void onTasksLoaded(List<Task> tasks) {
                view.showLoading(false);
                view.showTasks(tasks);
            }
            
            @Override
            public void onDataNotAvailable() {
                view.showLoading(false);
                view.showLoadingError();
            }
        });
    }
    
    // 其他方法实现...
}

View实现

public class TaskActivity extends AppCompatActivity implements TaskContract.View {
    private TaskContract.Presenter presenter;
    private TaskAdapter adapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_task);
        
        // 初始化Presenter
        presenter = new TaskPresenter(
            TaskRepository.getInstance(),
            this
        );
        
        // 初始化视图组件
        RecyclerView recyclerView = findViewById(R.id.task_list);
        adapter = new TaskAdapter();
        recyclerView.setAdapter(adapter);
        
        // 启动Presenter
        presenter.start();
    }
    
    @Override
    public void showTasks(List<Task> tasks) {
        adapter.setTasks(tasks);
        adapter.notifyDataSetChanged();
    }
    
    // 其他方法实现...
}

MVP优势分析

结构优势

- 关注点分离:UI逻辑与业务逻辑明确区分
- 模块独立性:各模块可独立开发和测试
- 代码复用:Presenter可跨多个View复用

开发效率

- 团队协作更高效,前端与后端开发可并行
- 接口定义明确,减少沟通成本
- 模块化程度高,便于功能扩展

维护性

- 代码职责清晰,易于理解
- 修改范围可控,降低连锁反应风险
- 问题定位准确,便于调试

MVP变种

Passive View

- View极度被动,几乎不包含任何逻辑
- Presenter控制一切UI交互和状态变化
- 最高程度的View-Model解耦

Supervising Controller

- View可以直接绑定简单数据
- Presenter仅处理复杂UI逻辑
- 在简单场景中可提高效率

MVP实践建议

接口设计

- 为每个功能模块定义明确的契约接口
- 根据单一职责原则拆分大型接口
- 避免"万能"接口导致耦合

生命周期管理

- 处理View生命周期变化(尤其在Android平台)
- 防止内存泄漏(弱引用、解绑操作)
- 优雅处理Presenter销毁逻辑

适用场景

- 复杂业务逻辑的企业级应用
- 需要高测试覆盖率的项目
- 多人协作的中大型项目

常见问题与解决方案

Presenter臃肿

随着业务复杂度增加,Presenter可能变得臃肿。解决方案:

- 引入UseCase/Interactor分担业务逻辑
- 按功能垂直拆分Presenter
- 结合依赖注入简化Presenter

额外代码量

MVP模式需要编写大量接口和委托代码。缓解方法:

- 使用代码生成工具
- 建立基类封装通用逻辑
- 只在复杂模块应用MVP,简单UI可使用其他模式

结语

MVP模式通过明确的职责划分和模块化设计,为应用开发提供了清晰的架构指导。在实际应用中,需要根据项目特点灵活调整其实现细节,避免教条化使用。随着响应式编程和MVVM模式兴起,MVP也在不断演进,但其核心理念仍然是现代软件设计的重要基石。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dontla

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值