一、什么是MVP模式?
MVP是MVC的变种,也是一种升级。要说MVP就要说说MVC,在MVC中Activity其实就是View层级,但是通常在使用中Activity也是Contrloller,并没有将View层和Controller层进行分离,耦合度大大提高,非常不利于项目的管理。所以也就产生了MVP。
二、MVC、MVP、MVVM区别和应用建议
类型 | 创建过程 | 特点 | 缺点 | 应用建议 |
---|---|---|---|---|
MVC | C->M+V | 分离了Model和Controller | Controller变得越来越复杂 | 简单的、不大修改的页面 |
MVP | V->P->M | 在MVC的基础上通过接口彻底分离了View和Model | Presenter与View的交互变得琐碎而复杂 | 核心、复杂、需求变更更快页面 |
MVVM | v->VM->M | 在MVP的基础上增加了DataBinding,代码量更小 | XML中包含代码,定位问题麻烦 | 核心、复杂、需求变更快页面 |
三、MVP架构设计
1. MVP三个角色
- View
- Presenter
- Model
2. 设计思想
MVP把Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成Presenter接口,Model层依然还是Model层。
在MVP模式中Activity的功能就是响应生命周期和显示界面,具体的逻辑在Presenter中完成,Presenter是Model和View层的桥梁,这样就把Model和View进行了隔离。
3. 如何设计
以下是我的项目中MVP模式的使用类图:
图中有几点需要注意:
- GankFragment直接依赖GankPresenter的实例,后面可以用Dagger进行解藕;
- GankPresenter依赖IModel,IView,面向接口接口编程。GankModel,GankPresenter,GankFragment分别实现各自的接口,IGankContract统一管理三者的接口,从而更方便了解P与M,P与V之间的调用关系。
- GankModel不直接封装数据层,而是依赖对应提供数据API的接口,面向接口编程,所以就不用关心底层提供数据的方式。实现各自接口的Impl实现类就可以实现二次封装,随时可以替换底层开源库。
4. RxJava+Retrofit的理解以及在MVP模式中使用
理解RxJava+Retrofit
5. 理解注解以及Dagger
全面解析注解和Dagger
6. 在MVP模式中使用Dagger
在MVP模式中,因为M、V、P三个角色都可能存在直接的依赖引用,所以在修改某个角色的时候,可能也需要修改另外一个依赖方。
比如在View层中有依赖Presenter,通过利用Dagger2就可以解除两者的依赖。
public class MainActivity extends AppCompatActivity implements MainContract.View {
@Inject
MainPresenter mainPresenter;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainComponent.builder()
.mainModule(new MainModule(this))
.build()
.inject(this);
//调用Presenter方法加载数据
mainPresenter.loadData();
...
}
}
public class MainPresenter {
//MainContract是个接口,View是他的内部接口,这里看做View接口即可
private MainContract.View mView;
@Inject
MainPresenter(MainContract.View view) {
mView = view;
}
public void loadData() {
//调用model层方法,加载数据
...
//回调方法成功时
mView.updateUI();
}
@Module
public class MainModule {
private final MainContract.View mView;
public MainModule(MainContract.View view) {
mView = view;
}
@Provides
MainView provideMainView() {
return mView;
}
}
@Component(modules = MainModule.class)
public interface MainComponent {
void inject(MainActivity activity);
}
对应项目地址:https://github.com/liuhe1993/myproject