wzgiceman / DaggerMvpDemo

演示Dagger2的使用法,结合Mvp实战演示

Home Page:http://blog.csdn.net/column/details/13413.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

#Dagger2-深入三(mvp结合使用)

##背景 mvp话说也出来很久了,初入学习Dagger的时候,就感觉和mvp结合能更加有效的解决presenter注入的的问题,避免更多的代码复写!而且大概看了下网络上的资源,一般多是分开讲解dagger和mvp技术,结合使用的很少,所以决定写出来和大家一起学习!

##何为MVP

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负责显示,所有通信都是单向的;

这里写图片描述

MVP 模式将 Controller 改名为 Presenter,同时改变了通信方向 这里写图片描述

  1. 各部分之间的通信,都是双向的。
  2. View 与 Model 不发生联系,都通过 Presenter 传递。
  3. View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。

因此我们可以发现MVP的优点如下:

1、模型与视图完全分离,我们可以修改视图而不影响模型;

2、可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部;

3、我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁;

4、如果我们把逻辑放在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实现 如何把mvp实现在我们的代码上呢?

这里写图片描述

可以从上面简单的demo的结构上看出,model和ui层都是提供了一个外部接口类,而presenter拥有这两个类的依赖,而MvpActivity拥有presenter的依赖,当MvpActivity触发事件后通过presenter触发事件处理model,当model处理完成以后通过ui外部接口类回调给activity!

##构建

###1.构建ui接口类

定义事件方法

public interface MvpUiImpl {
   void showTest(String msg);
}

###2.activity实现接口类

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);
    }
}

###3.model接口类 model接口定义处理数据方法

public interface MvpModelImpl {
    MvpEntity test();
}

###4.model具体实现类 实现具体的数据处理方法

public class MvpModel implements MvpModelImpl{

    @Override
    public MvpEntity test() {
        return new MvpEntity("数据");
    }
}

##presenter处理核心类 通过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

Dagger在mvp中的运用主要是优化Presenter创建依赖对象,所以开始我们的优化!

###1.创建MvpPresenterModule

既然需要得到一个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 对象

###2.构建Component 和传统Dagger构建一样,Component定义依赖的model,inject定义消耗的activity对象

@PerApp
@Singleton
@Component(modules = MvpPresenterModule.class)
public interface MvpPresenterComponent {

    void inject(MvpActivity activity);

}

###3.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);
    }
}

##结果 这里写图片描述

About

演示Dagger2的使用法,结合Mvp实战演示

http://blog.csdn.net/column/details/13413.html


Languages

Language:Java 100.0%