MVP架构最近很是火热,其实app架构并没有好坏之分,只要选择合适的,都OK的。一般小项目,功能不是很多的,业务逻辑写到 Activity 下面并无太多问题,但一旦业务逐渐变得复杂起来,每个页面之间有不同的数据交互和业务交流时,activity 的代码就会急剧膨胀,代码就会变得可读性,维护性很差,此时我们就可以考虑使用MVP架构。一般小公司app,其实都没必要使用MVP,个人浅见。当然MVP好处多多,层次清晰,易于测试,Activity代码更显精炼。这里,笔者使用豆瓣的API来演示一下MVP架构。
MVP,顾名思义:
View 对应于Activity,fragment,负责View的绘制以及与用户交互
Model 依然是业务逻辑和实体模型
Presenter 负责完成View于Model间的交互
图中所示,Model和View互不相干,靠Presenter维系交互。
以豆瓣读书搜索为例,首先分析下View层,需要下拉刷新,加载更多,加载提示,显示信息等功能,那么View代码可以写成如下:
public interface BookView {
void showLoading(String msg);
void hideLoading();
void refreshListData(List<Book> items);
void addMoreListData(List<Book> items);
void showMessage(String message);
}
再看P层代码
public interface BookPresenter {
void loadListData(String q, int start, int count);
void onItemClickListener(int position);
}
private Context mContext;
private BookView bookView;
private BookListInteractorImpl bookListInteractor;
public BookPresenterImpl(Context context,BookView bookView){
this.mContext = context;
this.bookView = bookView;
bookListInteractor = new BookListInteractorImpl(this);
}
@Override
public void loadListData(String q, int start, int count) {
bookListInteractor.getBookList(q,start,count);
}
@Override
public void onItemClickListener(int position) {
}
@Override
public void onSuccess(int tag,List<Book> data) {
if(tag == Common.REFRESH_DATA){
bookView.refreshListData(data);
}else if(tag == Common.LOADMORE_DATA){
bookView.addMoreListData(data);
}
}
@Override
public void onError(String msg) {
bookView.showMessage(msg);
}
@Override
public void onException(String msg) {
bookView.showMessage(msg);
}
}
从代码中可以看到Presenter持有View层和Model的接口,View负责UI显示,Model层负责数据获取,Presenter则负责调度View和Model。这里可以看出,即使设计还没出UI,我们也可以代码写起来。
再看下model层
public interface BookListInteractor { void getBookList(String q,int start,int count);}
在getBookList具体实现数据获取就OK了。
最后看下Activity
public class BookActivity extends AppCompatActivity implements BookView{
private Toolbar toolbar;
private XRecyclerView rv_list;
private List<Book> bookList = new ArrayList<>();
private BookAdapter adapter;
private BookPresenterImpl bookPresenter;
private int start = 0;
private String key;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.ac_book_layout);
toolbar = (Toolbar) findViewById(R.id.toolbar);
key = getIntent().getStringExtra("key");
bookPresenter = new BookPresenterImpl(BookActivity.this,this);
rv_list = (XRecyclerView) findViewById(R.id.rv_list);
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
SpaceItemDecoration space = new SpaceItemDecoration(12);
rv_list.addItemDecoration(space);
rv_list.setLayoutManager(manager);
adapter = new BookAdapter(this,R.layout.list_item_book,bookList);
rv_list.setAdapter(adapter);
rv_list.setLoadingListener(new XRecyclerView.LoadingListener() {
@Override
public void onRefresh() {
start = 0;
bookPresenter.loadListData(key,start,10);
}
@Override
public void onLoadMore() {
start +=10;
bookPresenter.loadListData(key,start,10);
}
});
bookPresenter.loadListData(key,start,10);
}
@Override
public void showLoading(String msg) {
}
@Override
public void hideLoading() {
}
@Override
public void refreshListData(List<Book> items) {
rv_list.refreshComplete();
bookList.clear();
bookList.addAll(items);
adapter.notifyDataSetChanged();
}
@Override
public void addMoreListData(List<Book> items) {
rv_list.loadMoreComplete();
bookList.addAll(items);
adapter.notifyDataSetChanged();
}
@Override
public void showMessage(String message) {
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
}
Activity实现了View以及持有Presenter实例,这样就妥了!
由此可以见MVP架构解决了View层和Model的耦合,大大减少了Activity的代码,业务逻辑与View分离,代码层次清晰,易于维护扩展。当然这里的代码只是演示MVP的写法,有不妥之处,欢迎吐槽。
本文代码demo:https://github.com/shuijilove/AndroidMVPDemo
Github上的一些MVP框架:
https://github.com/sockeqwe/mosby
https://github.com/kymjs/TheMVP