Android设计模式之浅谈MVP

一.概述

MVP(Model-View-Presenter) 是总所周知MVC模式的一个演变,他们的主要目的都是划分模块职责,降低模块耦合,易测试,提高代码复用,这里主要针对Android平台来简单分析MVP.

1.层级责任

Model: 负责数据的检索,持久化等操作

View: 负责UI的绘制和用户的交互

Presenter: 作为Model和View的中间协调部分,负责两者之间的业务逻辑处理

2.与MVC模式的区别

MVP模式与MVC模式从层级数据流向上来说一个主要的区别应该就是:MVC模式允许View层和Model层直接通讯.从图1和图2可以看到MVP和MVC的区别.

图1MVC模式中Model可以直接update data 到View层。所以当某个View的功能很复杂的时候,View和Model的耦合度可能会很高(并且在android的开发中Activity通常会充当controller&view的角色,结果Activity就很臃肿).而MVP模式就没有这个问题,View会抽象出来一系列操作UI的接口(Model层也可以),Presenter拿到的都是其他两个层级的接口来做业务逻辑的处理.这样不仅可以使View和Model之间的耦合度降低,还可以更易得进行单元测试.

这里写图片描述
图1:MVC模式
这里写图片描述
图2:MVP模式

3.MVP的优缺点

优点:降低耦合,层级职责更明显,易于单元测试

缺点:造成类数量爆炸,代码复杂度和学习成本高,在某些场景下presenter的复用会产生接口冗余

二. MVP简单的实例
使用MVP 写一个简单的登陆功能,主页就两个按钮:Login 和 Clear
1.项目结构

这里写图片描述

2.Model层

包含有一个实体UserBean用来承载数据和UserBiz来对登陆数据判断

public class UserBean {  
    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;  
    }  
}  

UserBiz通过抽象出一个接口

public interface UserBiz {  
    public void login(UserBean login);  
}  

UserBizImpl实例化接口,并且通过登陆监听将结果回调给Presenter

public class UsrBizImpl implements UserBiz{  
    private OnLoginListener listener;  

    public UsrBizImpl(OnLoginListener listener){  
        this.listener = listener;  
    }  

    @Override  
    public void login(UserBean login) {  
        boolean status = false;  
        String username,password;  
        username = login.getUsername();  
        password = login.getPassword();  
        if (username != null && "asdf".equals(username))  
            if (password != null && "123".equals(password))  
                status = true;  
        listener.loginStatus(status);  
    }  
}  

3.View层
把View层针对控件操作抽象出来一些列的接口

public interface LoginView {  
    public String getUsername();  
    public String getPassword();  
    public void clearUsername();  
    public void clearPassword();  
    public void showMsg(String msg);  
}  

在Activity里面实现该接口的控件操作,并且初始化Presenter,这是可以看到Activity里面没有逻辑处理,只是对UI的控件进行数据或者行为的操作,所有的动作都是有Presenter的接口来实现,这样在项目里面会极大得精简Activity的体积.

public class LoginActivity extends Activity implements LoginView{  
    private EditText username, password;  
    private Button login, clear;  
    private LoginPresenter loginPresenter;  

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

    private void init(){  
        loginPresenter = new LoginPresenterImpl(this);  
        username = (EditText) findViewById(R.id.username);  
        password = (EditText) findViewById(R.id.pass);  
        login = (Button) findViewById(R.id.login);  
        clear = (Button) findViewById(R.id.clear);  
        login.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View view) {  
                loginPresenter.login();  
            }  
        });  

        clear.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View view) {  
                loginPresenter.clear();  
            }  
        });  
    }  

    @Override  
    public String getUsername() {  
        return username.getText().toString();  
    }  

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

    @Override  
    public void clearUsername() {  
        username.setText("");  
    }  

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

    @Override  
    public void showMsg(String msg) {  
        Toast.makeText(this, msg, Toast.LENGTH_LONG).show();  
    }  
}  

4.Presenter层
在Presenter层里面,Presenter掌握着View和Model的所有接口,Presenter就可以根据不同的业务逻辑通过MV两层的接口来实现特定的功能,让M和V独立出来.

public class LoginPresenterImpl implements LoginPresenter, OnLoginListener{  
    private UserBiz userBiz;  
    private LoginView loginView;  

    public LoginPresenterImpl(LoginView loginView){  
        this.loginView = loginView;  
        userBiz = new UsrBizImpl(this);  
    }  

    @Override  
    public void login() {  
        UserBean login = new UserBean();  
        login.setUsername(loginView.getUsername());  
        login.setPassword(loginView.getPassword());  
        userBiz.login(login);  
    }  

    @Override  
    public void clear() {  
        loginView.clearPassword();  
        loginView.clearUsername();  
    }  

    @Override  
    public void loginStatus(boolean status) {  
        String msg;  
        if (status)  
            msg = "login succeed";  
        else  
            msg = "login failed";  
        loginView.showMsg(msg);  
    }  
}  

5.Demo下载地址
http://download.csdn.net/detail/qq_34476727/9615014

三.总结
简单得用了下MVP,也有跟朋友讨论了一下,好多人都说这个看着挺不错的,但是用着很麻烦。确实现在Android项目用MVP的不是占多数,带着一些疑惑楼主就想去了解一下android原生程序里面是用的什么风格的,之前也有看过一些android源码,但是都是断断续续的,也好久没有写过博客了,本着对技术的热爱,计划重新开启撸android源码的计划(从Android原生的系统程序到framework再一路向下),现在希望自己能够坚持下来,并且产出一个博客的系列和大家一起分享和成长.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值