Dagger2实现更为规范化的MVP架构

开始

关于Dagger2的使用可以参考之前的一篇文章 我的Dagger2学习历程:从一头雾水到恍然大悟。最近在修改项目结构的是否发现之前的MVP结构并没有完全遵循MVP模式,也没有做到面向接口的编程,这里做出一点补充。

代码

MVP由Model、View、Presenter构成,则我们的契约类Contract则要为这三者定义好接口

LoginContract.java

    public interface LoginContract {

        interface View extends IView {

            /**
             * 登录成功
             *
             * @param result
             */
            void loginSuccess(String result);
        }

        interface Presenter extends IPresenter{

            /**
             * 登录
             * @param mobile
             * @param password
             */
            void login(String mobile, String password);

        }

        interface Model extends IModel {

            /**
             * 登录
             *
             * @param mobile
             * @param password
             */
            Observable<String> login(String mobile, String password);

        }
    }

首先看View,这里是Activity。

LoginActivity.java

    public class LoginActivity extends BaseActivity<LoginContract.Presenter> implements LoginContract.View {

        @Override
        protected void setupActivityComponent(AppComponent appComponent) {
            DaggerLoginComponent
                    .builder()
                    .appComponent(appComponent)
                    .loginModule(new LoginModule(this))
                    .build()
                    .inject(this);
        }
    }

这里通过泛型将Presenter接口LoginContract.Presenter传入到BaseActivity中,在父类里面进行注入。

LoginPresenter.java

    @ActivityScope
    public class LoginPresenter extends BasePresenter<LoginContract.Model, LoginContract.View> implements LoginContract.Presenter {

        @Inject
        LoginPresenter() {
        }

        /**
         * 登录
         */
        @Override
        public void login(final String mobile, final String password) {
            mModel.login(mobile, password)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())

                    .........
                    .........
                    .........
        }
    }

同样这里把Model和View的接口通过BasePresenter进行注入,并实现LoginContract.Presenter接口,从这里可以看到M-V-P三者是缺一不可的。

Model同样如此。

Dagger注入的Module

LoginModule.java

    @Module
    public class LoginModule {
        private LoginContract.View view;

        public LoginModule(LoginContract.View view) {
            this.view = view;
        }

        @ActivityScope
        @Provides
        LoginContract.Model provideModel(LoginModel model) {
            return model;
        }

        @ActivityScope
        @Provides
        LoginContract.View provideView() {
            return this.view;
        }


        @ActivityScope
        @Provides
        LoginContract.Presenter providePresenter(LoginPresenter presenter) {
            return presenter;
        }
    }

最后由module提供M-V-P这三者的具体实现。唯一不太完美的地方是这里不能传接口类型了,只能传具体实现LoginPresenter和LoginModel,否则会报循环引用的错误,美中不足吧,不能真正实现全面向接口。 如果有更好的方法,欢迎指导,谢谢。

GitHub地址: https://github.com/a5533348/dagger2_MVP