之前有篇文章简要介绍了mvc设计模式,因为使用过于简单就没有具体的写案例,此篇文章将结果具体代码示例浅析并且使用mvp这个时下很流行的、职责清晰的设计模式。
简介
Model-模型:也就是业务逻辑。
V-View-视图:与用户交互的视图。
P-Presenter-表示器:控制M和V层的联系,相当于mvc模式中的controller。
在mvc模式中m和v层是糅杂在一起的,也就是是说view层的代码量非常的庞大,久而久之代码的可识别度大大降低,对程序猿来说,当需要修改业务逻辑时无疑是增加了工作量。而mvp设计中的presenter层正是来处理m层和v层的交互问题,也就是说当view层需要显示什么数据,那么就告诉presenter层,让p层去调用m层的方法,然后将处理结果在发送给view层,这样就完成了view层和model层的交互,逻辑清晰,同时model层只用专注于处理数据。
下面配上一张结构图:
mvp的优点
1.职责更清晰,高度解耦:view层只负责与用户交互,减少view层内的业务代码。model只负责去处理业务,这样就改善了mvc模式红v层和m层糅杂在一起的情况
2.代码扩展性更强
3.更容易迭代维护
4.有利于单元测试
mvp的缺点
1.学习成本变高
2.代码量变大,每个view都会对应自己的presenter,类会增多。
实例
上面的简单介绍应该对mvp有所理解,那就结合实例来掌握mvp的使用吧
这里不结合retrofit的网络请求,我们就来模拟一下吧,只是为了学习mvp设计的结构特点。
需求:mainactivity需要获取到文本数据展示
思路:mainactivity通知mainpresenter去控制mainmodel获取到文本数据,再由mainpresenter返回给mainactivity去展示。
- model的java文件
public class IMainModel {
//model获取数据
public void downLoad(final CallBack callBack) {
//....网络访问省略
String str = "能够拥有一份美丽的心情,不是因为我们获得的颇多,而是我们计较的很少;我们深深懂得,多,有时也是一种负担,是另外一种失去;少,并非真正不足,而是一种隐形的有余。很多的时候,我们审时度势,选择了舍弃,学会舍弃并不意味着全然失去,而是一种更宽阔更博大的获得!";
//将数据交给presenter
callBack.getResult(str);
}
public interface CallBack {
void getResult(String str);
}
}
这里由于没有用网络请求,我写了假的文本数据,并在此类中常见了CallBack接口,目的是为了将得到的数据返回给presenter层。
2.IMainView接口,大家一看知道,不多说了
public interface IMainView {
void onSuccess(String str);
void onFail(String msg);
}
3.MainPresenter 的逻辑代码
public class MainPresenter<IV> {
private Reference<IV> view;
private IMainView mIMainView;
private IMainModel mIMainModel;
public MainPresenter(IMainView mIMainView) {
this.mIMainView = mIMainView;
mIMainModel = new IMainModel();
}
public void downLoad() {
//presenter通知model去获取数据
mIMainModel.downLoad(mCallBack);
}
private IMainModel.CallBack mCallBack = new IMainModel.CallBack() {
@Override
public void getResult(String str) {
//presenter拿到model给的数据后,将数据返回给view层
mIMainView.onSuccess(str);
}
};
public void attachView(IV v) {
view = new WeakReference<>(v);
}
public IV getView() {
return view.get();
}
public void detachView() {
if (view != null) {
view.clear();
view = null;
}
}
}
4.MainActivity的java文件
public class MainActivity extends AppCompatActivity implements IMainView {
private TextView mTextView;
private Button mButton;
MainPresenter mMainPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.btn_download);
mTextView = (TextView) findViewById(R.id.text);
mMainPresenter = new MainPresenter(this);
mMainPresenter.attachView(this);
//点击下载图片
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//通知presenter去处理
mMainPresenter.downLoad();
}
});
}
@Override
public void onSuccess(String str) {
//view层拿到presenter返回的数据,更新UI
if (str.length() != 0) {
mTextView.setText(str);
}
}
@Override
public void onFail(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mMainPresenter != null) {
mMainPresenter.detachView();
mMainPresenter = null;
}
}
}
上面就是简单地代码,具体应该是button的点击→ mMainPresenter.downLoad()→ mIMainModel.downLoad(mCallBack)→ callBack.getResult(str)→ mIMainView.onSuccess(str) →mTextView.setText(str)
相信这样的结构还是比较一目了然的,各层各司其责,提高代码的扩展性。之后会写一篇mvp配合retrofit的完整篇。