热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Dagger2和MVP的结合

先挖个坑,这里会有两篇整理后的dagger2和MVP的博客链接dagger2入门MVP示例Da

        先挖个坑,这里会有两篇整理后的dagger2和MVP的博客链接

        dagger2 入门   MVP示例

         Dagger2通过注解的方式,来实现对象的统一管理(简化初始化);

         MVP 主要是减少Activity/Fragment的代码量,只留下清晰的数据和界面的衔接(或者说数据填充);通过使用接口搭建关系,将耦合甩给抽象出来的接口,表现上就是界面逻辑、数据交接集中到了P层;数据的计算、处理是在M层;

         mvp有一个明显的好处:即便没有界面,也可通过“单纯的Java”将业务处理完毕,以等带界面衔接。这一点尤其适用于美工瞎几把改图不断完善设计的情况。

 

        在我没有将这两个东西结合起来使用的时候,我一直认为这是一件很复杂的事:

       1.      P层持有的V的句柄是从界面传过来的,而界面持有P的实例来调用触发方法,就这么来看,一个PV的逻辑就要提供两个Component…..好恐怖的感觉。

       2.      MVP已经比普通的类数量增加了2~3倍,再加上dagger2的接近两倍,我的天呐!

       3.      没试过,劳资的内心就是抵触,怎么滴吧!

       接下来直接来个例子吧,废话少说(因为废话都在前两篇说够了),以登录作为典型案例来处理。

       V:

/**
* Created by ShuaiZhang on 2016/9/19.
* 定义接口包括四个方法,分别是获取用户名;获取密码;
* 显示登陆提示;显示登陆结果
*/
public interface ILoginView {
String getName();
String getPwd();
void showTip(String tip);
void setResult(String result);
}
        M:
/**
* Created by ShuaiZhang on 2016/9/19.
* 我不想说话,你么也别打我
*/
public class LoginBiz {
//把用户名和密码连接成一个串假,假装是登录
public String login(String name, String pwd){
String result = "UserName:" + name +"\nPassword:" + pwd;
return result;
}
}
        P:

/**
* Created by ShuaiZhang on 2016/9/19.
* MVP,我还是啥也不想说
*/
public class LoginPresenter {
private ILoginView loginView;
private LoginBiz loginBiz;

public LoginPresenter(ILoginView loginView) {
this.loginView = loginView;
loginBiz = new LoginBiz();
}

public void doLogin(){
loginView.showTip("Loading。。。");
String result = loginBiz.login(loginView.getName(), loginView.getPwd());
loginView.showTip("Success!");
loginView.setResult(result);
}
}

       为了增加篇幅,activity_login.xml:


android:orientation="vertical" android:layout_
android:layout_>

android:id="@+id/edt_name"
android:layout_
android:layout_ />

android:id="@+id/edt_pwd"
android:layout_
android:layout_ />

android:id="@+id/btn_login"
android:layout_
android:layout_
android:text="Login"/>


android:id="@+id/txt_show"
android:layout_marginTop="20dp"
android:layout_
android:layout_ />

       LoginActivity.class:

/**
* Created by ShuaiZhang on 2016/9/19.
* 登陆界面,实现登陆的抽象View ILoginView接口
*/
public class LoginActivity extends AppCompatActivity implements ILoginView {

LoginPresenter presenter;

@BindView(R.id.edt_name)
EditText edtName; // 用户名
@BindView(R.id.edt_pwd)
EditText edtPwd; // 密码
@BindView(R.id.btn_login)
Button btnLogin; //登录按钮
@BindView(R.id.txt_show)
TextView txtShow; //显示登录结果

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
ButterKnife.bind(this);
presenter = new LoginPresenter(this);//初始化presenter
//装X的拉姆达表达式
btnLogin.setOnClickListener(v -> {if(checkInput()) presenter.doLogin();});
}

//输入检查
private boolean checkInput(){
if (edtName.getText().toString().equals("")){
showTip("请输入姓名");
return false;
}
if (edtPwd.getText().toString().equals("")){
showTip("请输入密码");
return false;
}
return true;
}
//传递用户名
@Override
public String getName() {
return edtName.getText().toString();
}
//传递密码
@Override
public String getPwd() {
return edtPwd.getText().toString();
}
//显示提示
@Override
public void showTip(String tip) {
Toast.makeText(this,tip,Toast.LENGTH_SHORT).show();
}
//显示结果
@Override
public void setResult(String result) {
txtShow.setText(result);
}
}

        到这里,一个以Login为逻辑的MVP基本示例算是都有了。

        那么接下来,就是Dagger2了。

 

        想想前面三个疑问,握草,算了,还是慢慢写吧,先写个module试试?

/**
* Created by ShuaiZhang on 2016/9/19.
* 先写着试试
*/
@Module //为登录提供点东西
public class LoginModule {
//因为LoginPresenter构造器需要一个这玩意,所以放进了该Module的构造参数
//这样,在LoginActivity初始化时就必然传递该参数
private ILoginView loginView;
//有参数的module构造器要求必须显式的传入本实体 必须携带参数
public LoginModule(ILoginView loginView) {
this.loginView = loginView;
}

@Provides //这个注解表名会被自动处理
public LoginPresenter getLoginPresenter() {
return new LoginPresenter(loginView);
}
}

       Module有了,来个Component?

/**
* Created by ShuaiZhang on 2016/9/19.
* 这里决定怎么“组装”Component
* 1.决定伴随生命周期(inject方法和参数),
* 2.将会包含哪些实体(各module类中的@Provide返回类型)
*/
@Component(modules=LoginModule.class)//这里还可以有一个依赖,我没搞懂,没添加
public interface LoginActivityComponent {
void inject(LoginActivity activity);//有LoginActivity实现初始化,并绑定它的生命周期
}

       按照dagger2的套路下一步Build一下:

       注意:就是菜单栏的Build àRebuild Project;而Sync是没有用的,有时候这两个效果一样,但是这里不一样。

       接下来就是修改LoginActivity的代码了(只提供修改部分,因为其与的没差别):

@Inject
LoginPresenter presenter;
        为LoginPresenter添加@Inject注解,是它能自动获取dagger生成的对象。
//dagger不需要这里手动实现了
//presenter = new LoginPresenter(this);//初始化presenter
DaggerLoginActivityComponent.builder()//套路要求
.loginModule(new LoginModule(this))//显式传入,LoginPresenter必要的参数ILoginView
.build()//套路要求
.inject(this);//绑定生命周期

       这里注释掉不在需要的presenter的初始化,然后添加DaggerLoginActivityComponent的初始化(名字好特么长)。

        Dagger2对MVP的影响只是在关系建立的"方式"上,事实上不对MVP的逻辑关系造成任何影响。它甚至不改变连接的结构,而是以一种新的衔接形式。

        一句话描述:dagger2为mvp提供了一种新的、统配的方式来建立相互的联系。


       没了,写完了,dagger2+mvp就这样搞定了,我擦,那我前面的顾虑呢?好吧,回头再看一下:

       问题:P层持有的V的句柄是从界面传过来的,而界面持有P的实例来调用触发方法,就这么来看,一个PV的逻辑就要提供两个Component…..好恐怖的感觉。

       其实这是个误解,Presenter的实例化只是需要一个参数,这个参数是作为presenter的一部分,也就是presenter不再需要独立的Component。之所以我会有这个疑问,其实还是我自己对MVP的理解没有更好的深入,这个….

       问题:MVP已经比普通的类数量增加了2~3倍,再加上dagger2的接近两倍,我的天呐!

       这个是逻辑分块,清晰化后的代价,换句话说:吃好的,就要多花钱;其实逻辑方面的简洁是优于代码量增加带来的不便的,如果你还在纠结代码量增加了,那么我只能说:兄弟,你代码量还不够,继续加油吧!

       问题:没试过,劳资的内心就是抵触,怎么滴吧!

       两个字:呵呵!

 

       你们以为到这就完了?图样森破!

       现在来看,LoginBiz类是不需要参数的,好像prenter里面那样写,没啥问题,也对;但是既然我们有了dagger,那么我们为什么不试着让它“更加dagger2”一些呢?

       修改presenter的构造方法:

public LoginPresenter(ILoginView loginView, LoginBiz loginBiz) {
this.loginView = loginView;
this.loginBiz = loginBiz;
}

       这个时候LoginModule也需要修改:

@Provides //这个注解表名会被自动处理
public LoginPresenter getLoginPresenter() {
return new LoginPresenter(loginView,new LoginBiz());
}

        No!这不够dagger2!

        再改LoginModule:

@Provides //这个注解表名会被自动处理
public LoginPresenter getLoginPresenter(LoginBiz loginBiz) {
return new LoginPresenter(loginView,loginBiz);
}
@Provides
public LoginBiz getLoginBiz(){
return new LoginBiz();
}

        这里的getLoginPresenter的参数LoginBiz将会由下面的方法提供。


        那么,如何更加更加dagger2,接下来就自己开发吧,水平所限,我只能装逼到这了……

        提交的时候发现少个图,算了,哪天心情好哪天补上吧








推荐阅读
author-avatar
MrTkinG
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有