以前觉得自己了解了什么是MVP,还用自己理解MVP的概念写了一些“应用”。最近看了公司的代码,在同事的讲解下,才发现自己too young,根本没有了解到什么是MVP,完全是为了MVP而MVP。
MVX系列的架构(MVC、MVP、MVVM)目的在于将界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)相互分离,以达到高内聚低耦合的思想。至于使用其中哪一个具体的架构仅仅是手段而不是目的。
最终达到的效果就是各个层之间不依赖彼此而独立存在,每个层都可以单独拿出去进行测试,甚至直接移植到另一个项目上它也正常工作。
通常介绍MVP架构图示:
我之前的错误使用或者对MVP思想的误解如下:
- Presenter与View之间相互持有。
- 认为Java Bean(或称POJO)就是Model。
- 在Presenter进行过于具体的业务处理,Presenter变得臃肿。
- 使用混乱,在Presenter中随处引用Android相关的代码(甚至持有Context!)。
- View的接口定义过于具体而不是依赖于抽象。
使用后看似像一个有模有样的MVP,实际上各模块之间还是严重耦合,根本无法拿出单一模块进行单元测试。
目前看来,正确用法应该是这样:
- Presenter与View之间使用Contract层约定调用的接口,持有的是接口对象而不是对方。
- Model层不是实体对象!Model层中可包含有业务逻辑,通常是对一些核心对象的抽象。
- Presenter只处理大的逻辑流程,具体的数据业务处理由Model层完成。
- Presenter层(或Model层?)不该调用Android相关的资源,否则将使测试变得复杂。
- View的接口依赖于抽象,比如有一个加载完成的提示接口可以为
showLoadCompleteNotification()
,而不是showLoadCompleteToast()
或者showLoadCompleteText()
!