美文网首页
MVP模式-传统-添加dagger2-方便扩展的mvp(原创最全

MVP模式-传统-添加dagger2-方便扩展的mvp(原创最全

作者: 品味与回味 | 来源:发表于2017-07-02 16:44 被阅读36次

    开始讲之前希望大家懂一个概念 上通配符 下通配符<? entends *><? super *> 希望大家了解。这里我就不说了 如果有需要大家可以留言,我在写一个具体专题去讲讲。
    还有一个是mvp的大概了解。如果一点都不熟悉,那么您可能会看的比较吃力一些。

    1传统的mvp

    首先要先理解最开始mvp的最大作用就是解耦,降低每个之间的联系 所以我们做的做作用就是
    1 建立view的接口 Iview,这个接口的作用就是一点 让 view和P之间建立联系,
    下面我在啰嗦一点MVP这三个模块的相互之间的作用

    modle:它负责处理应用程序的数据部分。
    View:它负责在屏幕上设置特定数据的视图。
    p:它是连接一个模型和一个视图的桥梁。

    有不懂的 我给你解释一下
    View的唯一职责是依靠p的指示绘制UI(通过什么? 当然是接口 啊)
    modle和View没有直接通信。然后通过P勾勾搭搭。
    P 我要重点说一下 , 他的职责就是根据设计view需要的获取数据给modle。另外还有一些
    特别的事件要去通知view去更新页面

    下面来具体demo

    我们来写一个接口(很简单的了解就行)
    <pre>
    public interface ILoginView {
    void showLoading();
    void hideLoading();
    void showError(String msg);
    void LoginSuccess();
    }
    </pre>

    这是我们写的一个接口 用于 view和P之间的联系

    我们现在view中实现他
    <pre>
    public class LoginActivity extends AppCompatActivity implements ILoginView {

    略很多。

    public void login(View view) {
    loginPersenter.login(userName.getText().toString().trim(),password.getText().toString().trim());

    }这个就是接口的实现方法

    </pre>

    接下来我们来写model,这个是用于P中view中获取的数据和model交互。

    <pre>
    public interface ILoginModel {

    void login(String userName, String password,LoginListener listener);

    interface LoginListener {
    void loginSuccess();
    void loginFailed(String msg);
    }
    }

    public class LoginModelImpl implements ILoginModel {

    @Override
    public void login(String userName, String password, LoginListener listener) {
    new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
    if (userName.equals("flyou") && password.equals("553274238")) {
    listener.loginSuccess();
    } else {
    listener.loginFailed("用户名密码错误");
    }
    },2000);
    }
    }
    </pre>

    然后我去们写一个P
    <pre>
    public class LoginPersenter {
    private ILoginView loginView; 作为参数。用来P和view的绑定,来实现一种关系上的联系
    private ILoginModel loginModel;model

    public LoginPersenter(ILoginView loginView) {
    this.loginModel=new LoginModelImpl();
    this.loginView = loginView;
    }
    public void login(final String userName, final String password){
    loginView.showLoading();

            loginModel.login(userName, password, new ILoginModel.LoginListener() {
                @Override
                public void loginSuccess() {
                    loginView.hideLoading();
                    loginView.LoginSuccess();
                }
    
                @Override
                public void loginFailed(String msg) {
                    loginView.hideLoading();
                    loginView.showError(msg);
                }
            });
        }
       }
    

    }

    </pre>

    大家可以看到。当在view中有点击事件的时候 ,会调用p的login方法,并且吧editview的数据传递进去(账户密码),然后会调用view自身实现的showLoading()方法。给进来的数据会交给
    loginModel的方法。然后有返回数据的时候在通过loginView的方法进行绘制页面。 这个p就相当于一个中转货运站。 数据交互,页面怎么去更新都先告诉我,然后由P去告诉model怎么去处理数据、。view怎么去具体的更新页面。 说道这里,相信大家有一个大概的印象,那么下面来一点难度了 ,我们想要体现一下 自己能力了。 我们用dagger2

    2 在添加了dagger2时候怎么去用MVP

    说道这里的时候 给大家提前一个思考的环节(我们绑定的时候 还用接口 联系 P吗? 好多人说mvp的类多。写的多。我们可不可以简单一下?能不能不用构造方法。能不能写一个基类或者可以继承的类。方便去扩展呢? 带着这个疑问 我们来进入下面的环节)

    这个换件 不讲dagger2(想了解的可以留言。看状况是不是要单独去讲解。这里你知道dagger2是一种注释就可以。就是我不用new了。就可以获得我想要的对象)

    开始正题。 我们现在都用到了dagger2,还用到了 接口去绑定 ,哎 好掉价呀。怎么办呢 我们来想一想(这里要用到了 通配符了呦)
    我决定要写一个子类P

    <pre>

    public class Presenter<T extends Presenter.View> {

    private T view;

    public void setView(T view) {
    this.view = view;
    最精髓的一个方法。 这个就是绑定
    }

    public T getView() {
    return view;
    }

    public void initialize() {

    }

    public void terminate() {

    }

    public interface View {
    这个是我用来更新每个页面的方法。当然是在具体的情况的时候去填写方法。然后用公用的时候你现在就可以去填写 比如 有转圈(就可以写 void showGenxin() 理解就好。)
    }
    }
    好吧 我在多嘴多说一点 怕大家理解不到我说的通配符的概念。 我这里的T extends Presenter.View的作用就是告诉程序这个P是Presenter.View这个接口的子类

    </pre>
    下面 让我们是实现一个去了解一下
    [里面有一个部分rxjava2的代码。请搜本人的rxjava的学渣系列]
    <pre>

    public class CharactersPresenter extends Presenter<CharactersPresenter.View> {
    (CharactersPresenter.View这个就是Presenter.View接口的一个子类)
    private GetCharacters getCharacters;

    @Inject public CharactersPresenter(GetCharacters getCharacters) {

    this.getCharacters = getCharacters;
    

    }

    @SuppressWarnings("unchecked") @Override
    public void initialize() {
    super.initialize();
    this.getCharacters.execute(new GetCharacterListObserver());
    }

    @Override public void terminate() {
    super.terminate();
    getCharacters.dispose();
    setView(null);
    }

    private class GetCharacterListObserver extends UseCaseObserver<List<Character>> {

    @Override public void onComplete() {
      super.onComplete();
      getView().hideLoading();
    }
    
    @Override public void onError(Throwable e) {
      super.onError(e);
    }
    
    @Override public void onNext(List<Character> characters) {
      super.onNext(characters);
      getView().showCharacters(characters);
    }
    

    }

    public interface View extends Presenter.View {

    void showCharacters(List<Character> characters);
    
    void hideLoading();
    

    这两个方法就是我实现这个接口的时候 我要实现的特别的方法。 最这个view 有用的方法

    }
    </pre>

    然后 到了关键的时刻。 我要要去绑定了。

    在avtivity中 我要要怎么做
    <pre>

    @Inject CharactersPresenter presenter; 不懂dagger2的 不需要理解。 你知道这个就是我声明实例化了即可, 然后在oncreat中调用下面的方法
    当然这个avtivity implements CharactersPresenter.View {
    presenter.setView(this);
    presenter.initialize();

    </pre>
    哈哈 相信你已经看懂了。这个精妙的地方。我们不需要在重复的开写新的I***的view的接口,只需要在P中去写就完成了。 他的最大的贡献就是节省代码。让你的代码看着很舒服。

    3 当写第三点的时候 你要对 dagger2 rxjava2 等都要有点了解了。 毕竟我是在这两种情况下的扩展。节省代码量

    在我开始下面的情况下的时候 我上面说的基类P。其实并不完善。在复杂的情况下就有点鸡肋了。怎说呢。 我用到了通配符。这个概念。 他让我在扩展的时候能够很好的实现。但是一层还是不太够的,因为这里的MODEL我有一层 就是获取数据显示,并不复杂。 但是在复杂的程序的时候 ,数据库。后台服务。第三方的很多 都是数不胜数。我们怎么办?在每个具体的P实例化的时候去注视吗?这样代码重复两太大。 有人说 可以用基类去注释呀。 这里我要说 这是不行的。注释的参数我们获取不到,这个P 设计的时候就是为了绑定。,让具体的P去继承的。 所以构造方法没法去实现。并且。注释的(dagger2也不会注释Presenter,说道这里。dagger2还是需要大家去学习的要不这里你就会觉得去听天书。) 在application中我会提前把一些对象去注释掉。在我需要的时候去注入。直接可以用

    就像这样
    <pre>
    @Provides
    Repository provideCharacterRepository(DataSource dataSource) {
    return new CharacterRepository(dataSource);
    }
    </pre>

    你不需要上面这个方法的作用。他就是告诉你。通过new CharacterRepository(dataSource);获取到了Repository ,在你需要的时候可以用到。而之前那个P ,首先他是基类 ,

    这个P 很明显没有办法这样去用。因为P只是一个基类。(考虑一下)

    相关文章

      网友评论

          本文标题:MVP模式-传统-添加dagger2-方便扩展的mvp(原创最全

          本文链接:https://www.haomeiwen.com/subject/dwgncxtx.html