MVC和MVP --》deagger2

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。其中M层处理数据,业务逻辑等;V层处理界面的显示结果;C层起到桥梁的作用,来控制V层和M层通信以此来达到分离视图显示和业务逻辑层。
下面就列举登入的例子来了解MVC

module 层(主要是业务逻辑和数据的处理,下面是一个bean,也就是数据的处理 )

   public class User {
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public User() {
    }
    }

View层 处理界面的显示结果(布局文件)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.arvin.mvcmode.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <TextView
            android:textSize="18sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Username"/>

        <EditText
            android:id="@+id/username"
            android:layout_width="200dp"
            android:layout_height="wrap_content"/>
    </LinearLayout>

    <LinearLayout
        android:layout_marginTop="50dp"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:textSize="18sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Password"/>

        <EditText
            android:id="@+id/password"
            android:layout_width="200dp"
            android:layout_height="wrap_content"/>
    </LinearLayout>

<Button
    android:layout_marginTop="50dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="登入"
    android:onClick="login"
    android:layout_gravity="center_horizontal"
    android:textSize="18sp"/>
</LinearLayout>

controller层(来控制V层和M层通信以此来达到分离视图显示和业务逻辑层,主要是activity 和 fragment

public class MainActivity extends AppCompatActivity {

    private EditText mUsername;
    private EditText mPassword;
    private ProgressDialog dialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mUsername = (EditText) findViewById(R.id.username);
        mPassword = (EditText) findViewById(R.id.password);
        dialog = new ProgressDialog(this);
    }

    /**
     * 按钮点击
     *
     * @param view
     */
    public void login(View view) {
        String username = mUsername.getText().toString().trim();
        String password = mPassword.getText().toString().trim();
        dialog.show();
        //检查输入是否为空
        boolean checkUserInfo = checkUserInfo(username, password);
        if (checkUserInfo) {
            final User user = new User();
            user.setUsername(username);
            user.setPassword(password);
            new Thread() {
                @Override
                public void run() {
                    UserLoginNet userLoginNet = new UserLoginNet();
                    boolean login = userLoginNet.checkUserLoginInfo(user);
                    if (login){
                        //登入成功
                        success();
                    }else {
                        //登入失败
                        failed();
                    }
                }
            }.start();
        }
    }

    /**
     * 检验用户输入——界面相关逻辑处理
     *
     * @param username
     * @param password
     * @return
     */
    private boolean checkUserInfo(String username, String password) {
        if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) {
            return false;
        }
        return true;
    }
    /**
     * 登陆成功
     */
    public void success(){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // 登陆成功
                dialog.dismiss();
                Toast.makeText(MainActivity.this, getString(R.string.welcome)+mUsername.getText().toString(), Toast.LENGTH_SHORT).show();
            }
        });
    }




    /**
     * 登陆失败
     */
    public void failed(){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // 登陆失败
                dialog.dismiss();
                Toast.makeText(MainActivity.this, R.string.login_fail, Toast.LENGTH_SHORT).show();
            }
        });
public class UserLoginNet {
    /**
     * 登入验证
     */
    public boolean checkUserLoginInfo(User user){
        SystemClock.sleep(2000);//模拟登入耗时
        if ("username".equals(user.getUsername())&&"password".equals(user.getPassword())){
            return true;//登入成功
        }else {
            return false;//登入失败
        }
    }
}

这里写图片描述

使用传统的MVC,其中的View,对应的是各种Layout布局文件,但是这些布局文件中并不像Web端那样强大,能做的事情非常有限;Controller对应的是Activity,而Activity中却又具有操作UI的功能,我们在实际的项目中也会有很多UI操作在这一层,也做了很多View中应该做的事情,当然Controller中也包含Controller应该做的事情,比如各种事件的派发回调,而且在一层中我们会根据事件再去调用Model层操作数据,所以这种MVC的方式在实际项目中,Activity所在的Controller是非常重的,各层次之间的耦合情况也比较严重,不方便单元测试。

使用MVC的进化版——MVP,MVP中把Layout布局和Activity作为View层,增加了Presenter,Presenter层与Model层进行业务的交互,完成后再与View层交互(也就是Activity)进行回调来刷新UI。这样一来,所有业务逻辑的工作都交给了Presenter中进行,使得View层与Model层的耦合度降低,Activity中的工作也进行了简化

下面正对上面的mvc进行改造,需要把activity中的登入业务抽取出来
Presenter层与Model层进行业务的交互,完成后再与View层交互(也就是Activity)进行回调来刷新UI

presenter

public class MainActivityPresenter {
    MainActivity mMainActivity;

    public MainActivityPresenter(MainActivity mainActivity) {
        mMainActivity = mainActivity;
    }

    //登入业务的封装
    public void login(String username,String password){
        final User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        new Thread() {
            @Override
            public void run() {
                UserLoginNet userLoginNet = new UserLoginNet();
                boolean login = userLoginNet.checkUserLoginInfo(user);
                if (login){
                    //登入成功
                    mMainActivity.success();
                }else {
                    //登入失败
                    mMainActivity.failed();
                }
            }
        }.start();
    }
}
 public void login(View view) {
        String username = mUsername.getText().toString().trim();
        String password = mPassword.getText().toString().trim();
        dialog.show();
        //检查输入是否为空
        boolean checkUserInfo = checkUserInfo(username, password);
        if (checkUserInfo) {
            //开启业务,这里用实现m 和 c 的交互
            mMainActivityPresenter.login(username,password);
        }
    }

这里写图片描述

实现了 activity 只作为view

留心观察,在MainActivity的onCreate方法中,我们有创建业务层对象,还是存在一定的耦合,下面采用dagger2进行解耦。

mMainActivityPresenter = new MainActivityPresenter(this);

Dagger2配置

1.首先project的gradle中添加 apt插件

buildscript {
  dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
  }

2、apt插件的使用modle的gradle中添加

apply plugin: 'com.neenbedankt.android-apt'

3、添加dagger2的依赖 ,同步。

dependencies {
  compile 'com.google.dagger:dagger:2.6'
  apt 'com.google.dagger:dagger-compiler:2.6'
}

注解使用
@Module、@Provides、@Component、@Inject

@Module:标注对象创建的容器
@Provides:标识需要创建的对象
@Component:将创建好的对象与需要注入的对象组合到一起

完成dagger2的配置后,开始对代码解耦

  • 首先注入实例MainActivityPresenter 对象
 @Inject
    MainActivityPresenter mMainActivityPresenter;

既然要注入MainActivityPresenter 实例,就需要有创建实例的组件,所以通过@Module封装@Provides创建的实例

@Module
public class MainActivityModule {
    public MainActivityModule(MainActivity mainActivity) {
        mMainActivity = mainActivity;
    }

    MainActivity mMainActivity;
    @Provides
    MainActivityPresenter providerMainActivityPresenter(){
        return new MainActivityPresenter(mMainActivity);
    }
}

封装好实例后,需要@Component和注入@Inject关联

@Component(modules = MainActivityModule.class)
public interface MainActivityComponent {
    void in(MainActivity mainActivity);
}

完成上面工作后,bulid下工程,然后对代码解耦

//解耦前的代码
//mMainActivityPresenter = new MainActivityPresenter(this);

//解耦后  
     DaggerMainActivityComponent.builder().mainActivityModule(new MainActivityModule(this)).build().in(this);

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值