转载请标明出处:
http://blog.csdn.net/mollyxiong/article/details/54925663;
本文出自:【MollyShong博客】
一个简单的发送内容的demo 先上效果图
MVP模式的结构
一、什么是MVP模式?
分离view 与 model 层的功能,使得程序更加清晰 提高分离 解耦性,减轻activity的工作量 将业务代码单独抽取出来,各自负责各自层应该做的事情。简单一句话说就是基于MVC模式演变而来,提高代码结构清晰度,提高程序解耦性可维护性的模式。
接下来我们具体梳理下MVP究竟是什么
M 对应的Model 数据层,负责操作、获取数据
V 对应的是View 也就是Activity层,负责UI、与用户进行交互
P Presenter 就是我们要分离的业务逻辑层,连接view和model层,处理业务逻辑。
二、为什么要用MVP模式?
Android开发不同于JavaWeb开发的是利用MVC模式 使得控制器和展示层完全分离,但是Android中activity有控制器也有view做的事情,如果把布局文件单独分成view层,几乎就没有做什么事情,而activity还承担了部分view层的工作,到最后需求越来越多,activity也会越来也胖。所以在Android开发中可以使用MVP模式来清晰的分离各自层的工作。同样也利于单元测试。
三、MVP模式怎么用?
view层专门负责UI及用户交互
Persenter层负责所有的业务逻辑的处理
Model层负责数据的获取、操纵
各个层单独分离,用层与层之间用接口交互
下面我们来看一个简单的Demo
Acitivity 也就是view层 实现了ViewInterface接口,分离业务逻辑
public class MainActivity extends AppCompatActivity implements ViewInterface, View.OnClickListener {
private EditText content;
private EditText author;
private Button send;
private Button clean;
private ProgressBar loading;
private PresenterImpl presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
public void initView(){
content = (EditText) findViewById(R.id.content);
author = (EditText) findViewById(R.id.author);
loading = (ProgressBar) findViewById(R.id.loading);
send = (Button) findViewById(R.id.send);
clean = (Button) findViewById(R.id.clean);
send.setOnClickListener(this);
clean.setOnClickListener(this);
presenter = new PresenterImpl(this);
}
/**
* 显示和隐藏进度条
*/
@Override
public void showProgressBar() {
loading.setVisibility(View.VISIBLE);
}
@Override
public void hideProgressBar() {
loading.setVisibility(View.GONE);
}
/**
* 发送是成功还是失败各自需要做的事情
*/
@Override
public void sendSuccess() {
Toast.makeText(this,"发送成功!",Toast.LENGTH_SHORT).show();
}
@Override
public void sendFailed() {
Toast.makeText(this,"发送失败!",Toast.LENGTH_SHORT).show();
}
/**
* 清除发送内容
*/
@Override
public void cleanContent() {
content.setText("");
}
@Override
public void cleanAuthor() {
author.setText("");
}
/**
* 获取内容和作者
*/
@Override
public String getContent() {
return content.getText().toString().trim();
}
@Override
public String getAuthor() {
return author.getText().toString().trim();
}
/**
* Called when a view has been clicked.
* @param v The view that was clicked.
*/
@Override
public void onClick(View v) {
switch( v.getId()){
case R.id.send:
presenter.send();
break;
case R.id.clean:
presenter.clean();
break;
}
}
@Override
protected void onDestroy() {
presenter.destroy();
super.onDestroy();
}
}
ViewInterface
/**
* Created by Administrator on 2017/2/7.
* view 层的接口,定义view 的所有动作 view通常是指activity 让activity去实现本接口
* view 和 presenter 互相持有引用
*/
public interface ViewInterface {
/**
* 显示和隐藏进度条
*/
public void showProgressBar();
public void hideProgressBar();
/**
* 发送是成功还是失败各自需要做的事情
*/
public void sendSuccess();
public void sendFailed();
/**
* 清除发送内容
*/
public void cleanContent();
public void cleanAuthor();
/**
* 获取内容和作者
*/
public String getContent();
public String getAuthor();
}
业务逻辑层
/**
* Created by Administrator on 2017/2/7.
*
* 控制 业务层,处理所有的业务逻辑,连接view 和 model
*/
public interface PresenterInterface {
public void send();
public void destroy();
public void clean();
}
从view层获取数据 ,做完相应的业务处理,把事情交给model校验数据,返回结果,根据结果控制view做出相应的UI处理
/**
* Created by Administrator on 2017/2/7.
*/
public class PresenterImpl implements PresenterInterface {
ViewInterface viewInterface;
ModelImpl model;
private Handler mHandler = new Handler();
public PresenterImpl() {
}
public PresenterImpl(ViewInterface viewInterface) {
this.viewInterface = viewInterface;
model = new ModelImpl();
}
@Override
public void send() {
//显示进度条
viewInterface.showProgressBar();
model.send(viewInterface.getContent(), viewInterface.getAuthor(), new ModelInterface.OnSendLinterer() {
@Override
public void sendSuccess() {
mHandler.post(new Runnable() {
@Override
public void run() {
viewInterface.sendSuccess();
viewInterface.hideProgressBar();
}
});
}
@Override
public void sendFailed() {
mHandler.post(new Runnable() {
@Override
public void run() {
viewInterface.sendFailed();
viewInterface.hideProgressBar();
}
});
}
});
}
@Override
public void destroy() {
viewInterface = null;
model.destory();
model = null;
}
@Override
public void clean() {
viewInterface.cleanAuthor();
viewInterface.cleanContent();
}
}
数据层
/**
* Created by Administrator on 2017/2/7.
*
* 数据层,做的事情就是为Presenter层提供数据
*/
public interface ModelInterface {
interface OnSendLinterer{
void sendSuccess();
void sendFailed();
}
public void send(String content, String author, OnSendLinterer onSendLinterer);
}
发送数据请求发送内容是否成功,这里用的是模拟
/**
* Created by Administrator on 2017/2/7.
*/
public class ModelImpl implements ModelInterface {
private ExecutorService executorService ;
public ModelImpl(){
//获取一个线程池 根据 虚拟机可用的处理器的最大数量 +1 定义线程池大小
executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()+1);
}
@Override
public void send(String content, String author,final OnSendLinterer onSendLinterer) {
executorService.execute(new Runnable() {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
//模拟网络请求的耗时操作
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//随机boolean 模拟发送成功或失败
Random random = new Random();
if( random.nextBoolean() ){
onSendLinterer.sendSuccess();
}else{
onSendLinterer.sendFailed();
}
}
});
//不再接受新的任务
// executorService.shutdown();
/*try {
future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}*/
}
public void destory(){
executorService = null;
}
}
项目的结构
四、MVP模式什么时候用?
可能有朋友会觉得MVP是为了模式而模式,开发中类变得多了,感觉还更加复杂了。我们知道,当需求过多过于复杂的时候,activity的代码量就会越来越多,可能一个activity中会有几千行代码,极大的影响了后期的维护和开发的成本。如果用上MVP就能极大限度的将activity中展示 业务处理 数据存取单独分离出来,虽然类文件增加了不少,但是整体来看程序和代码的结构还是很清晰的。所以,应用层开发的项目个人觉得使用MVP都是比较合适的。
使用MVP模式,建议按功能分包,利于后面的维护和开发
最后附上Demo的下载链接: github
最后附上Demo的下载链接: github