MVVM

MVC      MVP     MVVM

三种常见的android架构。

  1. MVC
    MVC模式的意思是,分成三个部分.
    图片
  • view: 视图,用户界面(activity的layout)
  • controller: 控制器,业务逻辑
  • model : 模型, 数据保存

各部分直接保留着相互通信: 如下:
contact

  • view 传送指令到 controller
  • controller 完成业务逻辑后,要求model改变状态
  • model 将新的数据发送到view,用户得到反馈。

通信方式为单向。

  1. 互动模式
    接受用户模式时,MVC可以分为两种方式,一种是通过view接受指令,传递给controller。

另外一种是通过controller接受指令

MVP

MVP 模式将Controller 改名为 Presenter, 同时改变了通信方向。

  1. 各部分间的通信都是双向的.
  2. view 与model 不发生联系,都通过Presenter传递
  3. view 非常薄,不部署任何业务逻辑,称为“被动视图”(passive view)
    即没有任何主动性,而presenter非常厚,所有逻辑部署在那里。

MVP IN Android

在android里面使代码更加清晰,不过增加了很多类。

  • View : 将activity 视为View 层, 负责View 的绘制以及与用户的交互
  • Model : 依然是业务逻辑和实体模型
  • Presenter : 负责完成 View 与 Model 间的交互

文件夹 : MVP, 里面有bean, biz, prestener, view 等文件夹

Model

实体类User , 里面至少有一个业务方法,login().

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

    //get set 方法
    ...

}  

biz下创建一个接口 : IUserBiz

public interface IUserBiz {
    public void login(String username, String passward, OnLoginListener loginListener);
}

里面利用到了,另外一个接口OnLoginListener.

public interface OnLoginListener {
    void loginSuccess(User user);

    void loginFailed();
}                                                                                                                                                                                     

在biz 下 UserBiz

public class UserBiz implements IUserBiz {
    @Override
    public void login(final String username, final String password, 
            final OnListener loginListener) {
        //
        new Thread() {
            @Overdide 
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //模拟登录成功
                if (username.equals("...") && passward.equals("...")) {
                    User user = new User();
                    user.setUsername(username);
                    user.setPassword(password);
                    loginListener.loginSuccess(user);
                } else {
                    loginListener.loginFailed();
                }
            }
        }.start();
    }
}

在业务类,抽取了一个接口,一个实现类很常见,login(), 一般肯定是连接服务器的,是个耗时操作,
开了一个子线程,模拟了耗时,由于是耗时操作,所以通过一个回调接口来通知登录的状态。

waiting

这里大部分和以前的写法没区别。

View
Presenter 与View 交互式通过接口。定义一个ILoginView, 效果图:

有两个按钮,一个是login,一个是clear;
login说明要有用户名和密码,对应两个方法;
再者login是个耗时的操作,需要给用户一个友好的提示,一般加一个ProgressBar,所以有两个:

void showLoading();
void hideLoading();

login 还存在着登录成功和失败的处理,主要看成功去跳转activity,而失败去给个提醒:

void toMainActivity(User user);
void showFailedError();

clear 需要

void clearUserName();
void clearPassword();

综上: IUserLoginView接口完整为 :

public interface IUserLoginView {
    String getUserName();
    String getPassword();
    void clearUserName();
    void clearPassword();
    void showLoading();
    void hideLoading();
    void toMainActivity(User user);
    void showFailedError(); 
}

需要实现接口,方便很多。

对于View接口,去观察功能上的操作,然后考虑 :

  • 该操作需要什么 (getUserName, getPassword)
  • 该操作的结果,对应的反馈? (toMainActivity, showFailedError)
  • 该操作过程中对应的友好的交互 ? (showLoading, hideLoading)

view 的实现类 :

其实就是activity, MVP中的view其实就是activity.

public class UserLoginActivity extends ActionBarActivity implements IUserLoginView {

    private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);

    @Bind(R.id.username) protected EditText mEditUsername;
    @Bind(R.id.password) protected EditText mEditPassword;
    @Bind(R.id.login) protected Button mButtonLogin;
    @Bind(R.id.clear) protected Button mButtonClear;
    @Bind(R.id.progress_loading) protected ProgressBar mPbLoading;

    @OnClick(R.id.login) void login() {
        mUserLoginPresenter.login();
    }
    @OnClick(R.id.clear) void clear() {
        mUserLoginPresenter.clear();
    }


    @Override
    protected void onCreat(Bundle savedInstanceState) {
        super.onCreat(savedInstanceState);
        setContentView(R.layout.activity_user_login);
        ButterKnife.bind(this);
    }


    @Override
    public String getUserName() {
        return mEditUsername.getText().toString();
    }

    @Override
    public String getPassword() {
        return mEditPassword.getText().toString();
    }

    @Override
    public void clearUserName() {
        mEditUsername.setText("");
    } 

    @Override 
    public void clearPassword() {
        mEditPassword.setText("");
    }

    @Override
    public void showLoading()
    {
        mPbLoading.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoading()
    {
        mPbLoading.setVisibility(View.GONE);
    }

    @Override
    public void toMainActivity(User user)
    {
        Toast.makeText(this, user.getUsername() +
            " login success , to MainActivity", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showFailedError()
    {
        Toast.makeText(this,
            "login failed", Toast.LENGTH_SHORT).show();
    }

}

上面是view层.

在去看Presenter层, 里面的UserLoginPresenter
Presenter
presenter 作为mode 与view 之间交互的桥梁,

public class UserLoginPresenter {
    private IUserBiz userBiz;
    private IUserLoginView userLoginView;
    private Handler mHandler = new Handler();

    public UserLoginPresenter(IUserLoginView userLoginView) {
        this.userLoginView = userLoginView;
        this.userBiz = new UserBiz();  
    }

    public void login() {
        userLoginView.showLoading();
        userBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), 
                new OnLoginListener(){
            @Override
            public void loginSuccess(final User user)
            {
                //需要在UI线程执行
                mHandler.post(new Runnable()
                {
                    @Override
                    public void run() {
                        userLoginView.toMainActivity(user);
                        userLoginView.hideLoading();
                    }
                });

            }
             @Override
            public void loginFailed(){
                //需要在UI线程执行
                mHandler.post(new Runnable(){
                    @Override
                    public void run(){
                        userLoginView.showFailedError();
                        userLoginView.hideLoading();
                    }
                });
            }
        });

    }

    public void clear() {
        userLoginView.clearUserName();
        userLoginView.clearPassword();
    }
}

注意上面的代码里,presenter 完成view 和model的交互,需要二者的实现类,
是从view 中获取需要的参数,交给Model去执行业务方法,执行的过程需要的反馈,
以及结果,再让view进行对应的显示.

MVVM

MVVM 模式将presenter 改名为ViewModel, 基本上与MVP模式完全一致

唯一的区别是它采用了双向绑定(data-binding) : view 的变动,自动反映在
ViewModel, 反之亦然。

从 :

转变为 :

![](http://img.blog.csdn.net/20150622212856011)