Android设计架构:MVC/MVP

来源:互联网 发布:vue.js 显示隐藏 编辑:程序博客网 时间:2024/05/13 17:46
   最近在想写有关架构模式的博客,想了下目前自己接触的过就比较简单的就是MVP,MVC,其他比如MVVM什么的只是初步的了解一下,并没有实际的去实践过.   以前刚开始做Android的时候是做外包的,也是一边学一边写,架构模式什么的听说过,没实际写过,后面写了一两个之后,感觉很多地方都是在做重复劳动,有些新需求改动什么的,要从以前写的茫茫多的代码里面找到相应的地方修改,还不止改一个地方,哎,自己挖坑自己填.后来就开始逐渐使用架构模式,最初的是mvc,最近开始使用mvp.   说实在的,我们使用架构模式,是为了去实现那句"模块内部高聚合,模块之间低耦合",在使用过程中,开发效率的确能得到不少的提升,并且能方便功能测试以及定位问题.   但是,切忌不要为了架构而去架构,架构的初衷是为了提高效率以及为后续提供便捷,如果一个项目只有简单的几个java文件,而你还兴高采烈的去引入框架或者架构,将本来只需要做点功能模块划分的工作变得复杂,这就得不偿失了.   所以,对于不同量级的工程,要区别对待,同时在制定架构的同时也要和后台人员沟通协作好,毕竟团队协作,是一个项目能更好的完成的必不可少的条件之一.

聊到这里就差不多了,作为一个程序员的博客,怎么能只有文字没有代码呢?稍等,还有几行目录,看完就贴点代码,配合代码看起来更直观,方便理解.

  • 1.mvc
    • 1.1 mvc简介
    • 1.2 mvc在Android中的应用
  • 2.mvp
    • 2.1 mvp简介
    • 2.2 mvp在Android中的应用
  • 3.mvc与mvp的异同

1.MVC

1.1MVC简介

说道mvc大家肯定都很熟悉,model(模型)-view(视图)-controller(控制器).原理么简单说一下:1.View传送指令到Controller2.Controller完成业务逻辑,要求Model更改状态3.Model将新的数据发送到View,用户得到反馈所有通信都是单项的.这个图相信大家看过很多遍了吧,再看一遍加深下印象.

1.2MVC在Android中的应用

先上2个效果图.

贴上代码
/** *  Controller&View */public class MainActivity extends Activity implements onResultListener {    private EditText mInput;    private TextView mResult;    private UserModelImpl mUserImpl;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mUserImpl = new UserModelImpl();        init();    }    /**     * 初始化布局     */    private void init() {        mInput = (EditText) findViewById(R.id.input_text);        mResult = (TextView) findViewById(R.id.tv_result);    }    /**     * button 点击事件     * @param view     */    public void doMain(View view) {        mUserImpl.getData(mInput.getText().toString(), this);    }    /**     * 将结果打印出来     * @param result     */    public void showResult(String result) {        mResult.setText(result);    }    @Override    public void onSuccess(String result) {        showResult(result);    }    @Override    public void onFail() {        mResult.setText("这里只有hong,ling,jin,没有其他人");    }}
/** * Model模型 */public interface DataModel {    void getData(String text,onResultListener listener);}.................public class UserModelImpl implements DataModel {    @Override    public void getData(String text, onResultListener listener) {        //这里偷懒下,我写点假数据,假装我是从别的地方获取数据的        List<User> users = UserData.getData();        boolean isExist = false;        for (int i = 0; i < users.size(); i++) {            //判断传入的人名是否存在            if (text.equals(users.get(i).getName())) {          listener.onSuccess(users.get(i).toString());                isExist = true;            }        }        if (!isExist) {            listener.onFail();        }    }}
从上面代码可以看出Activity持有了UserModel对象,当用户点击button之后,Activity作为控制层从View层的EditText中获得数据,然后向Model层发送数据请求,处理完毕之后,通过onResultListener通知View层数据处理完毕并更新UI页面.整体MVC框架就在Activity中体现出来了.稍微去关注下Model层那段代码,这里有一个DataModel模型接口,一个实现了该接口的UserModelImpl类.Activity控制器通过调用UserModelImpl中的getData方法处理数据,后通过onResultListener返回结果,通知View层刷新页面.讲句明白话,这里Activity将View层的显示以及Model的数据处理给隔开了,也就是说activity担当controller很好的完成了model和view之间的协调工作.

2.MVP

2.1MVP简介

MVP是从更早的MVC框架演变而来的,与MVC有一定的相似性:


View负责绘制UI,与用户进行交互.
Model负责处理数据.
Presenter作为view和model交互的中间纽带,处理与用户交互的逻辑.
另外此模式下还有些特性:
1、模型与视图完全分离,我们可以修改视图而不影响模型;
2、更高效地使用模型,因为所有的交互都发生在Presenter内部;
3、Presenter可以在不修改逻辑的前提下,多次复用.
4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)。

说到这里,举个简单的例子:
UI层通知逻辑层(Presenter)用户点击了一个Button,逻辑层(Presenter)自己决定应该用什么行为进行响应,
该找哪个模型(Model)去做这件事,最后逻辑层(Presenter)将完成的结果更新到UI层。

2.2 MVP在Android中的应用

这个是此框架在app中的包结构图:

建立Bean:

public class UserBean {    private String mFirstName;    private String mLastName;    public UserBean(String mFirstName, String mLastName) {        this.mFirstName = mFirstName;        this.mLastName = mLastName;    }    public String getmFirstName() {        return mFirstName;    }    public String getmLastName() {        return mLastName;    }}

建立model:

public interface IUserModel {    void setID(int id);    void setFirstName(String firstName);    void setLastName(String lastName);    int getID();    UserBean load(int id);//根据id去查用户信息}

这个是model 的接口,实现就不写了,自己新建个java文件实现这个接口即可.

Presenter:通过Model,IView的接口来操作view和model,activity将所有逻辑交给presenter来处理.

public class UserPresenter {    private IUserView mUserView;    private IUserModel mUserModel;    public UserPresenter(IUserView view) {        this.mUserView = view;        mUserModel = new UserModel();    }    public void saveUser(int id,String firstName,String lastName){        mUserModel.setID(id);        mUserModel.setFirstName(firstName);        mUserModel.setLastName(lastName);    }    public void loadUser(int id){        UserBean bean = mUserModel.load(id);        mUserView.setFirstName(bean.getmFirstName());        mUserView.setLastName(bean.getmLastName());    }}

View:列出了当前view所需要的操作方法,也是个接口

public interface IUserView {    int getID();    String getFirstName();    String getLastName();    void setFirstName(String firstName);    void setLastName(String lastName);}

activity实现了IView接口,并在其中操作view,实例化了一个presenter对象.

public class MainActivity extends Activity implements IUserView {    private UserPresenter mPresenter;    private EditText mInputId, mInputFirst, mInputLast;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_mvp);        init();        mPresenter = new UserPresenter(this);    }    private void init() {        mInputId = (EditText) findViewById(R.id.input_id);        mInputFirst = (EditText) findViewById(R.id.input_firstname);        mInputLast = (EditText) findViewById(R.id.input_lastname);    }    public void doSave(View view) {        mPresenter.saveUser(getID(), getFirstName(), getLastName());    }    public void doLoad(View view) {        mPresenter.loadUser(getID());    }    @Override    public int getID() {        return new Integer(mInputId.getText().toString());    }    @Override    public String getFirstName() {        return mInputFirst.getText().toString();    }    @Override    public String getLastName() {        return mInputLast.getText().toString();    }    @Override    public void setFirstName(String firstName) {        mInputFirst.setText(firstName);    }    @Override    public void setLastName(String lastName) {        mInputLast.setText(lastName);    }}

刚开始看肯定不明白这个是什么,为什么要这样写,我就这么点代码还要分那么多文件?
首先,刚开始看到这模式的确会有点不适应,刚接触新事物嘛,如果不会,照着上面这个例子自己写一遍,再好好体会一下.
其次,上面只是个例子,方便初步理解一下mvp到底长什么样子,说了那么多还是要看代码才能一目了然.
还有就是先实现功能,再考虑代码重构,一直在那边思考代码到底臃肿不臃肿,用什么方式去写,不知道什么时候才能写好.

MVC与MVP的异同

先说一下共同点,也是最直观的,就是View和Model:
- Model模型–数据对象,提供本应用对外部应用程序数据操作的接口,也可以在内部数据发生变化时发出通知的,而且本身不依赖于View,可以通过调用接口来对数据进行操作.
- View视图–UI层,提供给用户操作功能以及以及展现UI页面和一些相关的逻辑操作.

两种模式的主要区别:
mvc的时候,view可以和model直接交互,不能做到真正的低耦合,如果代码量一大,则会在activity里面越写越多,到后面自己都不想去看那些写的奇奇怪怪的代码了.
而map下,View与Presenter是一对一的,如果你的view很复杂的话,可以绑定多个Presenter来处理逻辑,并且他们之间是通过接口来进行交互的,可以很方便的添加单元测试.

结语

最后提一下MVVM,MVVM可以算是MVP的升级版,这可不是Model,View,View,Model4个元素混在一起,后面2个VM是ViewModel的缩写.ViewModel可以理解成为是View和Presenter的合体,ViewModel和View之间的交互式通过DataBinding完成的,而且DataBinding可以实现双向交互,进一步的降低view和model之间的耦合程度.
还有在我们实际使用的时候,不必纠结到底使用哪个模式好,选择恐惧症的毛病犯起来可得浪费不少时间,只要能更方便快捷实现项目需求,那就是最适合的架构,不必在意是否过时.

1 0
原创粉丝点击