Android:MVC/MVP/MVVM 架构

1、架构

1、架构:将系统进行模块/组件/角色的划分,建立角色之间(数据结构/事件等)的通信机制。

2、需求

1、用户输入账号名称->点击查询账户信息->展示查询成功失败结果。
在这里插入图片描述

3、不使用架构

1、activity_architecture.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <android.support.v7.widget.AppCompatEditText
        android:id="@+id/etAccount"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:hint="请输入查询信息?" />

    <android.support.v7.widget.AppCompatButton
        android:id="@+id/btnGetAccount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获取账号信息" />

    <android.support.v7.widget.AppCompatTextView
        android:id="@+id/tvResult"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="--" />
</android.support.v7.widget.LinearLayoutCompat>

2、NormalActivity.java


public class NormalActivity extends AppCompatActivity implements View.OnClickListener {

    /**
     * 输入查询信息
     */
    private AppCompatEditText etAccount;
    /**
     * 展示查询结果
     */
    private AppCompatTextView tvResult;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_architecture);
        initView();
    }

    /**
     * 初始化数据
     */
    private void initView() {
        etAccount = findViewById(R.id.etAccount);
        tvResult = findViewById(R.id.tvResult);
        findViewById(R.id.btnGetAccount).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnGetAccount:
                getAccountData(getAccount(), new ICallback() {
                    @Override
                    public void onSuccess(Account account) {
                        showSuccess(account);
                    }

                    @Override
                    public void onFailed() {
                        showFailed();
                    }
                });
                break;
        }
    }

    /**
     * 查询获取用户数据
     *
     * @param accountName
     * @param callback
     */
    private void getAccountData(String accountName, ICallback callback) {
        Random random = new Random();
        boolean isSuccess = random.nextBoolean();
        if (isSuccess) {
            Account account = new Account();
            account.setName(accountName);
            account.setLevel(100);
            callback.onSuccess(account);
        } else {
            callback.onFailed();
        }
    }

    /**
     * 获取用户输入信息
     *
     * @return
     */
    private String getAccount() {
        return etAccount.getText().toString();
    }

    /**
     * 获取用户信息成功
     *
     * @param account
     */
    private void showSuccess(Account account) {
        tvResult.setText("账户名:" + account.getName() + ",账户等级:" + account.getLevel());
    }

    /**
     * 获取用户信息失败
     */
    private void showFailed() {
        tvResult.setText("获取数据失败!");
    }
}

4、MVC 模型

1、MVC (Model-View-Controller):模型-视图-控制器。
2、Model:获取数据(网络请求,SQL等);View:layout、View控件;Controller:Activity、Fragment;数据通信:数据结构 和 事件。
在这里插入图片描述
3、优点:实现 Model 与 View 分离,降低代码耦合。
4、缺点:Controller 与 View 难以解耦,项目越复杂 Controller 越臃肿。
5、例子:

  1. View:activity_architecture.xml 见 上文。
  2. Model:MvcModel
public class MvcModel {

    /**
     * 查询获取用户数据
     *
     * @param accountName
     * @param callback
     */
    public void getAccountData(String accountName, ICallback callback) {
        Random random = new Random();
        boolean isSuccess = random.nextBoolean();
        if (isSuccess) {
            Account account = new Account();
            account.setName(accountName);
            account.setLevel(100);
            callback.onSuccess(account);
        } else {
            callback.onFailed();
        }
    }
}
  1. Controller
public class MvcActivity extends AppCompatActivity implements View.OnClickListener {

    /**
     * 输入查询信息
     */
    private AppCompatEditText etAccount;
    /**
     * 展示查询结果
     */
    private AppCompatTextView tvResult;

    private MvcModel mMvcModel;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_architecture);
        initView();
    }

    /**
     * 初始化数据
     */
    private void initView() {
        etAccount = findViewById(R.id.etAccount);
        tvResult = findViewById(R.id.tvResult);
        findViewById(R.id.btnGetAccount).setOnClickListener(this);
        mMvcModel = new MvcModel();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnGetAccount:
                mMvcModel.getAccountData(getAccount(), new ICallback() {
                    @Override
                    public void onSuccess(Account account) {
                        showSuccess(account);
                    }

                    @Override
                    public void onFailed() {
                        showFailed();
                    }
                });
                break;
        }
    }

    /**
     * 获取用户输入信息
     *
     * @return
     */
    private String getAccount() {
        return etAccount.getText().toString();
    }

    /**
     * 获取用户信息成功
     *
     * @param account
     */
    private void showSuccess(Account account) {
        tvResult.setText("账户名:" + account.getName() + ",账户等级:" + account.getLevel());
    }

    /**
     * 获取用户信息失败
     */
    private void showFailed() {
        tvResult.setText("获取数据失败!");
    }
}
5、MVP 模型

1、MVP (Model-View-Presenter):模型-视图-控制器。
在这里插入图片描述
2、MVP 与 MVC 差异:Modle 与 View 不直接通信,通过 Presenter 实现通信;Activity 功能简化,主要负责 View 层的工作。
3、优点:解决 MVC 中 Controller 与 View 耦合的缺点,职责划分明显,更易于维护。
4、缺点:接口数量多,项目越复杂 Presenter 层越臃肿。
5、例子:

  1. Model
public class MvpModel {

    /**
     * 查询获取用户数据
     *
     * @param accountName
     * @param callback
     */
    public void getAccountData(String accountName, ICallback callback) {
        Random random = new Random();
        boolean isSuccess = random.nextBoolean();
        if (isSuccess) {
            Account account = new Account();
            account.setName(accountName);
            account.setLevel(100);
            callback.onSuccess(account);
        } else {
            callback.onFailed();
        }
    }
}
  1. Presenter
public class MvpPresenter {
    private IMvpView mView;
    private MvpModel mModel;

    public MvpPresenter(IMvpView view) {
        this.mView = view;
        mModel = new MvpModel();
    }

    public void getAccountData(String accountName) {
        mModel.getAccountData(accountName, new ICallback() {
            @Override
            public void onSuccess(Account account) {
                mView.showSuccess(account);
            }

            @Override
            public void onFailed() {
                mView.showFailed();
            }
        });
    }
}
  1. View:activity_architecture.xml 见 上文。
public interface IMvpView {
    /**
     * 获取用户输入信息
     * @return
     */
    String getAccount();

    /**
     * 获取用户信息成功
     * @param account
     */
    void showSuccess(Account account);

    /**
     * 获取用户信息失败
     */
    void showFailed();
}

public class MvpActivity extends AppCompatActivity implements View.OnClickListener, IMvpView {

    /**
     * 输入查询信息
     */
    private AppCompatEditText etAccount;
    /**
     * 展示查询结果
     */
    private AppCompatTextView tvResult;

    private MvpPresenter mPresenter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_architecture);
        initView();
    }

    /**
     * 初始化数据
     */
    private void initView() {
        etAccount = findViewById(R.id.etAccount);
        tvResult = findViewById(R.id.tvResult);
        findViewById(R.id.btnGetAccount).setOnClickListener(this);
        mPresenter = new MvpPresenter(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnGetAccount:
                mPresenter.getAccountData(getAccount());
                break;
        }
    }

    /**
     * 获取用户输入信息
     *
     * @return
     */
    @Override
    public String getAccount() {
        return etAccount.getText().toString();
    }

    /**
     * 获取用户信息成功
     *
     * @param account
     */
    @Override
    public void showSuccess(Account account) {
        tvResult.setText("账户名:" + account.getName() + ",账户等级:" + account.getLevel());
    }

    /**
     * 获取用户信息失败
     */
    @Override
    public void showFailed() {
        tvResult.setText("获取数据失败!");
    }
}
6、dataBinding 使用

1、DataBinding:谷歌推出的数据绑定框架。
2、使用:

  1. 启用 DataBinding
// build.gradle
android {
    // 1.启用dataBinding
    dataBinding{
        enabled = true
    }
}
  1. 布局转为 DataBinding 布局:alt+enter->Convert to data binding layout。
  2. 数据绑定
7、MVVM 模型

1、MVVM (Model-View-ViewModel):模型-视图-视图模型。实现数据视图绑定(DataBinding),数据变化视图自定更新,视图变化数据也会自动更新。
在这里插入图片描述
2、MVVM 优点:实现数据和视图的双向绑定简化代码;减少接口数量;不需要 findViewById 操作。
3、MVVM 缺点:bug 难调试,dataBinding 编译不及时。
4、例子:

  1. Model
public class MvvmModel {

    /**
     * 查询获取用户数据
     *
     * @param accountName
     * @param callback
     */
    public void getAccountData(String accountName, ICallback callback) {
        Random random = new Random();
        boolean isSuccess = random.nextBoolean();
        if (isSuccess) {
            Account account = new Account();
            account.setName(accountName);
            account.setLevel(100);
            callback.onSuccess(account);
        } else {
            callback.onFailed();
        }
    }
}
  1. View
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="viewModel"
            type="com.strugglelin.architecture.mvvm.MvvmViewModel" />
    </data>

    <android.support.v7.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal"
        android:orientation="vertical">

        <android.support.v7.widget.AppCompatEditText
            android:id="@+id/etAccount"
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:hint="请输入查询信息?"
            android:text="@={viewModel.userInput}" />

        <android.support.v7.widget.AppCompatButton
            android:id="@+id/btnGetAccount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{viewModel.getAccountData}"
            android:text="获取账号信息" />

        <android.support.v7.widget.AppCompatTextView
            android:id="@+id/tvResult"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="@{viewModel.result}" />
    </android.support.v7.widget.LinearLayoutCompat>
</layout>
  1. ViewModel
public class MvvmViewModel extends BaseObservable {

    private Application application;
    private MvvmModel model;
    private ActivityMvvmBinding binding;
    private String result;
    private String userInput;

    @Bindable
    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
        notifyPropertyChanged(BR.result);
    }

    @Bindable
    public String getUserInput() {
        return userInput;
    }

    public void setUserInput(String userInput) {
        this.userInput = userInput;
        notifyPropertyChanged(BR.userInput);
    }

    public MvvmViewModel(Application application) {
        this.application = application;
        model = new MvvmModel();
    }

    public MvvmViewModel(Application application, ActivityMvvmBinding binding) {
        this.application = application;
        model = new MvvmModel();
        this.binding = binding;
    }

    public void getAccountData(View view) {
//        final String accountName = binding.etAccount.getText().toString();
        model.getAccountData(userInput, new ICallback() {
            @Override
            public void onSuccess(Account account) {
                String info = account.getName() + "|" + account.getLevel();
                setResult(info);
            }

            @Override
            public void onFailed() {
                setResult("获取数据失败!");
            }
        });
    }
}
public class MvvmActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMvvmBinding binding;
        binding = DataBindingUtil.setContentView(this, R.layout.activity_mvvm);
        MvvmViewModel model = new MvvmViewModel(getApplication());
        binding.setViewModel(model);
    }
}

注:TheArchitecture Demo

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值