MVP第一个小demo

MVP概念:

    1.Model:业务逻辑和实体模型
    2.View:View通常来说是由Activity实现的,它会包含一个Presenter的引用,View要做的就只是在每次有接口调用的时候(比如按钮点击后)调用Presenter的方法。
    3.主要作为沟通ViewModel的桥梁,它从Model层检索数据后,返回给View层,但是不像MVC结构,因为它也可以决定与View层的交互操作。

MVP优缺点:

优点:
    1. 降低耦合度,实现了ModelView真正的完全分离,可以修改View而不影响Modle

    2. 模块职责划分明显,层次清晰(下面会介绍Bob大叔的Clean Architecture3. 隐藏数据

    4. Presenter可以复用,一个Presenter可以用于多个View,而不需要更改Presenter的逻辑(当然是在View的改动不影响业务逻辑的前提下)

    5. 利于测试驱动开发。以前的Android开发是难以进行单元测试的(虽然很多Android开发者都没有写过测试用例,但是随着项目变得越来越复杂,没有测试是很难保证软件质量的;而且近几年来Android上的测试框架已经有了长足的发展——开始写测试用例吧),在使用MVP的项目中PresenterView是通过接口进行,在对Presenter进行不依赖UI环境的单元测试的时候。可以通过Mock一个View对象,这个对象只需要实现了View的接口即可。然后依赖注入到Presenter中,单元测试的时候就可以完整的测试Presenter应用逻辑的正确性。

    6. View可以进行组件化。在MVP当中,View不依赖Model。这样就可以让View从特定的业务场景中脱离出来,可以说View可以做到对业务完全无知。它只需要提供一系列接口提供给上层操作。这样就可以做到高度可复用的View组件。

    7. 代码灵活性

缺点:

    1. Presenter中除了应用逻辑以外,还有大量的View->ModelModel->View的手动同步逻辑,造成Presenter比较笨重,维护起来会比较困难。

    2. 由于对视图的渲染放在了Presenter中,所以视图和Presenter的交互会过于频繁。

    3. 如果Presenter过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密。一旦视图需要变更,那么Presenter也需要变更了。

    4. 额外的代码复杂度及学习成本。

MVP小demo:模拟一个用户登录程序
1. 首先是用户bean对象 没什么好解释的

public class UserInfo {

    private int userId;
    private String username;
    private String password;

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

    public String getUsername() {
        return username;
    }

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

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getPassword() {
        return password;
    }

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

2. Model接口和它的实现类

/**
 * Created by zlc on 2017/2/5.
 * 定义登录,保存用户和读取用户信息的方法
 */
public interface IUserModel {

    boolean saveUserInfo(int userId,String userName,String passWord);
    UserInfo getUserInfo(int userId);
    boolean login(String userName,String passWord);
}
/**
 * Created by zlc on 2017/2/5.
 * Model具体实现类 分别实现上述三个方法 实现具体逻辑
 */
public class UserModelImpl implements IUserModel {


    private Map<Integer,UserInfo> userInfoMap;
    public UserModelImpl(){
        userInfoMap = new HashMap<>();
    }


    @Override
    public boolean saveUserInfo(int userId, String userName, String passWord) {

        UserInfo userInfo = new UserInfo(userName,passWord);
        userInfoMap.put(userId,userInfo);
        return true;
    }

    @Override
    public UserInfo getUserInfo(int userId) {

        return userInfoMap.get(userId);
    }

    @Override
    public boolean login(String userName, String passWord) {

        if("zlc".equals(userName) && "zlc123".equals(passWord)){
            return true;
        }else{
            return false;
        }
    }

}

3. View接口定义

public interface IUserView {
    int getUserId();   //获取用户输入的用户id
    String getUserName(); //获取用户输入的用户名
    String getPassWord(); //获取用户输入的密码
    void setUserId(int userId);  //这个主要是取用户信息数据回填用户id  一下同
    void setUserName(String userName);
    void setPassWord(String passWord);
}

4. Presenter定义:包含View接口和Model实现类的引用,Model层获取数据,返回给Vew层。

public class UserPresenter {

    private IUserModel userModel;
    private IUserView userView;
    private Context mContext;

    public UserPresenter(Context context,IUserView view){
        userModel = new UserModelImpl();
        this.mContext = context;
        this.userView = view;
    }

    public boolean saveUserInfo(int userId,String userName,String passWord){
        if(TextUtils.isEmpty(userId+"") || TextUtils.isEmpty(userName) || TextUtils.isEmpty(passWord)){
            Toast.makeText(mContext, "用户ID 或者 用户名 或者 用户密码不能为空", Toast.LENGTH_SHORT).show();
            return false;
        }
        return userModel.saveUserInfo(userId, userName, passWord);
    }

    public void getUserInfo(int userId){
        if(userId==0){
            Toast.makeText(mContext, "用户ID不能为0", Toast.LENGTH_SHORT).show();
            return;
        }
        UserInfo userInfo = userModel.getUserInfo(userId);
        if(userInfo==null){
            Toast.makeText(mContext, "用户信息不存在", Toast.LENGTH_SHORT).show();
            userView.setUserId(userId);
            userView.setUserName("");
            userView.setPassWord("");
            return;
        }
        userView.setUserId(userId);
        userView.setUserName(userInfo.getUsername());
        userView.setPassWord(userInfo.getPassword());
    }


    public boolean login(String userName,String passWord){
        return userModel.login(userName,passWord);
    }
}

5. Activity实现,实现View接口,包含Presenter的应用,具体逻辑都是通过调用Presenter里面的方法去实现 减少Activity代码的长篇大论。

public class MainActivity extends AppCompatActivity implements IUserView,View.OnClickListener{

    private UserPresenter userPresenter;
    private EditText id_et_userid;
    private EditText id_et_username;
    private EditText id_et_pwd;
    private Button id_btn_login;
    private Button id_btn_save;
    private Button id_btn_get;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        userPresenter = new UserPresenter(MainActivity.this,this);
        initUI();
        initListener();

    }

    private void initUI() {

        id_et_userid = (EditText) findViewById(R.id.id_et_userid);
        id_et_username = (EditText) findViewById(R.id.id_et_username);
        id_et_pwd = (EditText) findViewById(R.id.id_et_pwd);
        id_btn_login = (Button) findViewById(R.id.id_btn_login);
        id_btn_save = (Button) findViewById(R.id.id_btn_save);
        id_btn_get = (Button) findViewById(R.id.id_btn_get);
    }

    private void initListener() {
        id_btn_get.setOnClickListener(this);
        id_btn_save.setOnClickListener(this);
        id_btn_login.setOnClickListener(this);
    }

    @Override
    public int getUserId() {
        int userId = !TextUtils.isEmpty(id_et_userid.getText().toString()) ? Integer.valueOf(id_et_userid.getText().toString()) : 0;
        return userId;
    }

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

    @Override
    public String getPassWord() {
        return id_et_pwd.getText().toString();
    }

    @Override
    public void setUserId(int userId) {
        id_et_userid.setText(userId+"");
    }

    @Override
    public void setUserName(String userName) {
        id_et_username.setText(userName);
    }

    @Override
    public void setPassWord(String passWord) {
        id_et_pwd.setText(passWord);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.id_btn_get:
                userPresenter.getUserInfo(getUserId());
                break;
            case R.id.id_btn_save:
                boolean save = userPresenter.saveUserInfo(getUserId(), getUserName(), getPassWord());
                String saveStatus = save ? "成功" : "失败";
                Toast.makeText(MainActivity.this, "保存"+saveStatus, Toast.LENGTH_SHORT).show();
                break;
            case R.id.id_btn_login:
                boolean login = userPresenter.login(getUserName(), getPassWord());
                String  loginStatus = login ? "成功" : "失败";
                Toast.makeText(MainActivity.this, "登录"+loginStatus, Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

6. 总结

MVP适合大项目,小项目反而会多了很多接口,不易理解,但是一旦项目很多,优点自是好处多多,写的不好的地方望多多见谅,本人菜鸟一枚,刚刚入坑mvp,学习学习,写个博客纯属做点笔记。

7. 源代码下载

   http://download.csdn.net/detail/rjgcszlc/9752914

8. 联系方式:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值