我实践中的mvp架构
2016-01-21 10:09
633 查看
我实践中的mvp架构
在Android开发实践中,我也深刻理解到一个项目的架构稀烂会带来什么,成天的找bug,解决了一个bug,又出现了两个bug,这样的事肯定会经常出现。所以呢我决定使用传说中的mvp,这是15年年底的事,经过这么久了,想想也可以稍微写点东西。MVP架构介绍
MVP架构图对比
总结
mvp架构介绍
参考软件架构的依赖规则:
软件是分层的,高层是基础业务逻辑和策略,低层是实现机制和展现形式。代码和数据依赖只能是低层代码依赖高层,而不能反过来。
什么是MVP?
MVP是Model, View和Presenter的简称。是非常有名的MVC模式的演化版。MVP模式把显示逻辑和从业务逻辑层中分离出来,理想状况下,MVP模式中,在替换不同的视图(View)的情况下,可以实现完全相同的业务逻辑。
Presenter代替了MVC中Controller,它比Controller担当更多的任务,也更加复杂。Presenter处理事件,执行相应的逻辑,这些逻辑映射到Model的Command以操作Model。那些处理UI如何工作的代码基本上都位于Presenter。Presenter如同一个乐队的指挥家,表现和协调整个Application,它负责创建和协调其它对象。
MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从直接Model中读取数据而不是通过 Controller。
为什么使用MVP模式
因为在Android中,Activity严重耦合了界面和数据获取层。这样不仅导致了Activity的类越来越庞大,而且,如果修改数据获取层,可能也导致整个View都要重写。也非常不利于模块和自动化测试。
MVP使View独立于数据,把大量的逻辑从Activity中提取出来。把应用分层,每层都可以独立测试和变动。
MVP模式是如何工作的
MVP模式中的角色划分并没有标准的划分方法。大致的定义如下:
表示器(Presenter)
表示器也可以称为指挥器,它处在View和Model之间,负责从Model中获取数据,然后返回给View。同时决定视图上的交互的处理。
视图(View)
视图比较好理解,在Android中一般对应的是Activity,Fragment或者View。因为视图上的交互需要通知表示器,让它决定做什么事情。所以View中一般包含一个Presenter的引用。理想状况下,Presenter一般使用依赖注入的方式实现。
模型(Model)
模型是应用程序中的数据处理和业务逻辑部分。
MVP架构图对比
传说中的mvp架构图:传说中的mvp架构图实现代码
具体代码请参考:https://github.com/ray0807/ShareFramework
其实从代码中也可以看到一个activity就会跟一个IView 当然啦,这也是为了更好的解耦和,本人是从心底里赞同的,但是有些小项目,说实在的,需要更敏捷,更快速,所以呢,我自己在开发的时候也有一套自己的实现方式,实现原理图与上面的原理图差不多
ZebraPresenter(购物车presenter)这里是整个模块的presenter,并不是一个activity就有一个IView,这里的IView被presenterCallback代替,传回的数据也有T 代替(这样就可以满足一个presenter传递多种数据啦)
/** * 购物车实现 * @author wangl01 * */ public class ZebraPresenter extends Presenter { private PresenterCallBack callback; private ZebraGoManager manager; private Page currentPage; public ZebraPresenter(PresenterCallBack callback) { manager = new ZebraGoManager(); this.callback = callback; } private <T> void sendData(PresenterData<T> data) { if (callback != null) { callback.callBackPresenter(data); } } public void getZebraProductShowList(Context c) { manager.getZebraGoHomepage(c, new NListener<BaseData>() { @Override public void onResponse(BaseData data) { List<ZebraHomePageProductBean> productTypeList = null; List<ZebraHomePageBusinessBean> businessList = null; if (data.status == 0) { productTypeList = data.data.productTypeList; businessList = data.data.businessList; } sendData(new PresenterData<List<ZebraHomePageProductBean>>("zebra_product", productTypeList)); sendData(new PresenterData<List<ZebraHomePageBusinessBean>>("zebra_onsell", businessList)); } @Override public void onErrResponse(VolleyError error) { sendData(new PresenterData<List<ZebraHomePageProductBean>>("zebra_product", null)); sendData(new PresenterData<List<ZebraHomePageBusinessBean>>("zebra_onsell", null)); } @Override public void onAllPageLoaded(int nowPage, int totalPage) { } }); }
acitivity实现
/** * 购物车 * @author wangl01 * */ public class ZebraShoppingCarActivity extends BaseActivity implements OnClickListener, PresenterCallBack, OnItemClickListener, OnRefreshListener2<SwipeMenuListView> { private NavigationBar navbar_activity_shopping; private LoadingSwipeMenuListView smls_shoppingCar; private ZebraGoShoppingCarAdapter adapter; private ZebraPresenter presenter; private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case Constant.FRESH_COMPLETE: smls_shoppingCar.onRefreshComplete(); break; default: break; } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.ac ac02 tivity_zebra_shopping_car); EventBus.getDefault().register(this); findViews(); init(); addListeners(); } @Override protected void onDestroy() { EventBus.getDefault().unregister(this); super.onDestroy(); } @Override public void findViews() { presenter = new ZebraPresenter(this); } @Override public void init() { //节省空间,不需要的代码已被删除 presenter.getZebraShoppingCar(this, isRefresh); } /** * presenter 回调 */ @Override public <T> void callBackPresenter(PresenterData<T> data) { refreshComplete(); T t = data.data; if (t == null) { return; } //为了简化,此处我用的字符串,亲们不要学我 if ("zebra_shopping_car".equals(data.tag)) { shoppingCarData = (List<ShoppingCarBean>) t; if (shoppingCarData != null) { setShoppingCar(); } } if ("completed".equals(data.tag)) { int flag = (Integer) t; if (flag == 0) { refreshComplete(); smls_shoppingCar.disableLoading(); smls_shoppingCar.OnLoadingFinished(); } } if ("ZebraBusinesSsettle".equals(data.tag)) { BaseData bean = (BaseData) t; if (bean != null) { if (bean.status == 0) { //```` } else { ToastMgr.show("结算失败"); } } } }
看看项目结构(亲们不要吐槽我还在使用eclipse,公司要求,其实我的内心还是属于Android studio)
结合上面的代码,其实你会发现我全工程只有一个IView接口,但是数据类型都是可以回传的,这里还是感谢java泛型的功劳。
总结
总结下我这样做有什么好处呢。其实我的项目中会少很多接口,你也不用写view 的时候使劲的去定义IView接口,毕竟一开始大家都不会花太多时间去定义数据结构(至少我不会),所以呢我不会给定你数据结构,给你一个T ,你可不要打我(这可不是打篮球)。再者想想,我只有一个IView接口,接口是不是少了很多?类也少了很多。写起来得心应手啊有木有。一个T 解决数据结构
接口只需要定义一个
同样有mvp结构带来的便利(我曾经一天调了将近20个接口,当然是稍微简单的接口)
好咯,有兴趣请关注我的github:https://github.com/ray0807/
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories