mvp话说也出来好久了,初入学习Dagger的时候,就感受和mvp结合能更加有效的解决presenter注入的的问题,避免更多的代码复写!并且大概看了下网络上的资源,通常可能是分开讲解dagger和mvp技术,结合使用的不多,因此决定写出来和你们一块儿学习!html
MVP,全称 Model-View-Presenter,要说MVP那就不得不说一说它的前辈MVC。
MVC(Model-View-Controller,模型-视图-控制器)模式是80年代Smalltalk-80出现的一种软件设计模式,后来获得了普遍的应用,其主要目的在于促进应用中模型,视图,控制器间的关注的清晰分离。MVP(Model-View-Presenter,模型-视图-表示器)模式则是由IBM开发出来的一个针对C++和Java的编程模型,大概出现于2000年,是MVC模式的一个变种,主要用来隔离UI、UI逻辑和业务逻辑、数据。也就是说,MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示,全部通讯都是单向的;java
MVP 模式将 Controller 更名为 Presenter,同时改变了通讯方向git
一、各部分之间的通讯,都是双向的。github
二、View 与 Model 不发生联系,都经过 Presenter 传递。编程
三、 View 很是薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter很是厚,全部逻辑都部署在那里。设计模式
所以咱们能够发现MVP的优势以下:网络
一、模型与视图彻底分离,咱们能够修改视图而不影响模型;ide
二、能够更高效地使用模型,由于全部的交互都发生在一个地方——Presenter内部;单元测试
三、咱们能够将一个Presenter用于多个视图,而不须要改变Presenter的逻辑。这个特性很是的有用,由于视图的变化老是比模型的变化频繁;学习
四、若是咱们把逻辑放在Presenter中,那么咱们就能够脱离用户接口来测试这些逻辑(单元测试)。
具体到Android App中,通常能够将App根据程序的结构进行纵向划分,根据MVP能够将App分别为模型层(M),UI层(V)和逻辑层(P)。
UI层通常包括Activity,Fragment,Adapter等直接和UI相关的类,UI层的Activity在启动以后实例化相应的Presenter,App的控制权后移,由UI转移到Presenter,二者之间的通讯经过BroadCast、Handler或者接口完成,只传递事件和结果。
举个简单的例子,UI层通知逻辑层(Presenter)用户点击了一个Button,逻辑层(Presenter)本身决定应该用什么行为进行响应,该找哪一个模型(Model)去作这件事,最后逻辑层(Presenter)将完成的结果更新到UI层
如何把mvp实如今咱们的代码上呢?
能够从上面简单的demo的结构上看出,model和ui层都是提供了一个外部接口类,而presenter拥有这两个类的依赖,而MvpActivity拥有presenter的依赖,当MvpActivity触发事件后经过presenter触发事件处理model,当model处理完成之后经过ui外部接口类回调给activity!
定义事件方法
public interface MvpUiImpl {
void showTest(String msg);
}复制代码
public class MvpActivity extends AppCompatActivity implements MvpUiImpl{
MvpPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mvp);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
presenter.testDoS();
}
});
}
@Override
public void showTest(String msg) {
TextView tv=(TextView)findViewById(R.id.tv);
tv.setText(msg);
}
}复制代码
model接口定义处理数据方法
public interface MvpModelImpl {
MvpEntity test();
}复制代码
实现具体的数据处理方法
public class MvpModel implements MvpModelImpl{
@Override
public MvpEntity test() {
return new MvpEntity("数据");
}
}复制代码
经过ui和model对象的引用对象,事件触发后调用数据model处理方法,成功后回调给ui界面
public class MvpPresenter {
MvpUiImpl ui;
MvpModelImpl model;
public MvpPresenter(MvpUiImpl ui, MvpModelImpl model) {
this.ui = ui;
this.model = model;
}
public void testDoS() {
MvpEntity entity = model.test();
ui.showTest(entity.getMsg());
}
}复制代码
经过上面简单的构建,到这里一个传统的mvp构建就算是完成了!可是 MvpPresenter类初始化须要传递的两个依赖对象,这里正好咱们可使用dagger2的依赖注入实现MvpPresenter,减小程序的耦合度!
Dagger在mvp中的运用主要是优化Presenter建立依赖对象,因此开始咱们的优化!
既然须要获得一个Presenter,首先须要构建一个对应的module
@PerApp
@Module
public class MvpPresenterModule {
private MvpActivity activity;
public MvpPresenterModule(MvpActivity activity) {
this.activity = activity;
}
@Provides
MvpActivity provideActivity(){
return activity;
}
@Provides
MvpPresenter providePresenter(MvpActivity ui,MvpModel mvpModel){
return new MvpPresenter(ui,mvpModel);
}
@Provides
MvpModel provideMvpModel(){
return new MvpModel();
}
}复制代码
注意:看完这段代码估计有同窗发现,和以前的model构建好像不同呀,对!这里咱们在MvpPresenterModule 中首先提供了两个@Provides定义的方法,一个方法提供了MvpActivity ,另外一个提供了一个MvpModel 对象;而这两个不正式初始MvpPresenter的依赖注入对象嘛!
是的这里咱们经过dagger自带的@Provides方法,首先提供了两个MvpPresenter初始须要的对象,而后在@Provides定义一个MvpPresenter providePresenter(MvpActivity ui,MvpModel mvpModel)
方法,让Dagger自动为咱们建立一个MvpPresenter 对象
和传统Dagger构建同样,Component定义依赖的model,inject定义消耗的activity对象
@PerApp
@Singleton
@Component(modules = MvpPresenterModule.class)
public interface MvpPresenterComponent {
void inject(MvpActivity activity);
}复制代码
public class MvpActivity extends AppCompatActivity implements MvpUiImpl{
@Inject
MvpPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mvp);
MvpPresenterComponent component= DaggerMvpPresenterComponent.builder().mvpPresenterModule(new MvpPresenterModule(this))
.build();
component.inject(this);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
presenter.testDoS();
}
});
}
@Override
public void showTest(String msg) {
TextView tv=(TextView)findViewById(R.id.tv);
tv.setText(msg);
}
}复制代码
若有帮助欢迎start和留言!