Android MVP架构浅析(续)
来源:互联网 发布:学软件发展前景好不 编辑:程序博客网 时间:2024/05/20 00:37
继前篇博文对MVP架构做了简单解析之后遗留的问题还是挺多的,所以接下来的几篇我会慢慢重构它,尽量避免由于梯度过大而使初学者产生疑惑。关于架构设计我没有比较深刻的理解,经过几个项目的实战后,我总结了一句话:所谓设计,即在变与不变间斟酌;您是否从这句话看出了面向对象设计的理念—抽象,我觉得你是可以领悟到的,否则你就不会阅读本文了,那我们今天就先从变与不变开始吧。上篇文章中有段代码,不知你还否记得:
/** * Created by 小雨 on 2015/11/15. */public class FeedPresenter { private FeedView mFeedView; public FeedPresenter(FeedView feedView) { this.mFeedView = feedView; } public void loadFeedList() { this.mFeedView.showFeedList(FeedDataStoreFactory.getInstance().getFeedStoreData()); }}
我们为View创建一个接口是毋容置疑的,但是Presenter拿到View句柄的方式是可以优化的,既然是面向接口编程,那么当前Presenter的依赖对象(View)注入形式是有问题的,已具体到功能模块,这是我们最不愿看到的。插入一段似乎不太合适的话,项目的包组织结构问题,有人喜欢按组件分,有人喜欢按功能分,不管最终以什么维度来划分,意向都是一样的,我们都希望代码结构看着整洁,那就从包结构着手吧,就像重构后的demo,我对包结构做了下调整,上层按组件分,下层按功能分,别问我为什么这么分,因为我喜欢…… 我还是稍作解释一下吧,不然有些同学肯定会打我的! 数据层(data)向表示层(presentation)提供数据,presentation并不关注data从哪里拿到的数据,DataStoreFactory负责具体执行,cache 、net or disk,这些都是data的职责,作为表示层我只负责展示就好了,不该我管的事我不管。presentation按功能模块划分包组织结构,基层构建放在根包下,其它按具体功能划分。
回到刚才Presenter依赖注入方式的问题。问题的本质就是我们把实现耦合了—多么痛的领悟… 应该依赖于抽象而不是依赖于具体! 所以先从接口抽象重构。 View的接口抽象定义:
/** * Created by 小雨 on 2015/11/15. */public interface MvpView {}
如你所见,MvpView接口并没有定义任何行为方法,它的作用就是把View从具体功能中抽象出来。
像刚才说的那样,Presenter的依赖应该被抽象出来,得到和失去本是天生一对,Presenter接口的抽象定义:
/** * Created by 小雨 on 2015/11/15. */public interface MvpPresenter<V extends MvpView> { void attachView(V view); void detachView(boolean retainInstance);}
Presenter接口定义好了,该如何管理View的句柄呢(何时注入? 何时销毁?),我们不可能把这些交给具体业务实现中去做吧,这样就违背了设计的初衷了Presenter持有View句柄的方式我们依然需要抽象出来,所以就有了下面这段代码:
/** * Created by 小雨 on 2015/11/15. */public abstract class MvpBasePresenter<V extends MvpView> implements MvpPresenter<V> { private V mView; @Override public void attachView(V view) { this.mView = view; } protected V getView() { return this.mView; } protected boolean isViewAttached() { return this.mView != null; } @Override public void detachView(boolean retainInstance) { this.mView = null; }}
需要注意一点的是必须在onDestroy()中调用detachView释放与view解绑。
Presenter管理View句柄的问题已经解决,那View如何持有Presenter的句柄呢,代码如下:
/** * Created by 小雨 on 2015/11/15. */public abstract class MvpBaseActivity<P extends MvpPresenter> extends AppCompatActivity implements MvpView { protected P presenter; protected abstract P createPresenter(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); presenter = createPresenter(); if (presenter == null) { throw new NullPointerException("Presenter is null! Do you return null in createPresenter()?"); } presenter.attachView(this); } @Override protected void onDestroy() { super.onDestroy(); presenter.detachView(false); }}
MvpBaseActivity管理着View何时被注入到Presenter中,又是何时从Presenter中移除的。createPresenter()作为一个钩子延迟到子类去实现,多态的表现。
重构后的抽象基础构件已经定义好,现在时候是时候派上用场了,重构后的FeedPresenterImpl需要继承MvpBasePresenter,同时实现FeedPresenter接口即可
/** * Created by 小雨 on 2015/11/15. */public class FeedPresenterImpl extends MvpBasePresenter<FeedView> implements FeedPresenter { public FeedPresenterImpl() { } @Override public void loadFeedList() { if (isViewAttached()) { getView().showFeedList(FeedDataStoreFactory.getInstance().getFeedStoreData()); } }}
因为Presenter仅以弱引用形式持有View句柄,所以每次使用前View需要判定View是否已经被销毁掉。
和FeedPresenterImpl类似,FeedActivity需要继承MvpBaseActivity,同时实现FeedView接口,具体实现代码:
/** * Created by 小雨 on 2015/11/15. */public class FeedActivity extends MvpBaseActivity<FeedPresenter> implements FeedView { private ListView vFeedListView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); vFeedListView = (ListView) findViewById(R.id.feed_list); init(); } private void init() { presenter.loadFeedList(); } @Override public void showFeedList(List<Feed> feedList) { vFeedListView.setAdapter(new FeedAdapter(feedList)); } @Override protected FeedPresenter createPresenter() { return new FeedPresenterImpl(); }}
至此,我们的重构告一段落了,也许你对本次重构稍有疑惑,但我相信你多看一遍就会理解。如一开始所说,本文只是重构的一环,所以你的持续关注是我前进的动力哈。
实例源码github地址:https://github.com/Tiny-Times/android-mvp2
- Android MVP架构浅析(续)
- Android MVP架构浅析
- Android MVP架构浅析
- 浅析android的mvp架构
- MVX Android设计架构浅析-MVP
- MVP架构浅析
- 架构探险——Android MVP模式浅析
- 浅析MVP(Model-View-Presenter)架构及开发模式
- MVP (1)- Android mvp 架构的自述
- Android MVP架构学习(附demo)
- Android架构(一)MVP全解析
- Android架构(一)MVP全解析
- Android架构(一)MVP全解析
- Android MVP架构(Volley+CursorLoader+ContentProvider)
- Android中的MVP架构总结(一)
- Android中MVP架构总结(二)
- Android架构(一)MVP全解析
- android MVP架构
- 第131讲:Hadoop集群管理工具均衡器Balancer 实战详解学习笔记
- 114 linux shell find grep xargs学习
- web服务器集群session同步、共享的3种解决方法
- UIImageView的属性之animationImages详解
- andorid 简单的自定义相机
- Android MVP架构浅析(续)
- 【Android】Scheme详解
- OC学习心得之Block
- 一般处理程序ashx 处理JQuery的Ajax()请求
- 用Python读取大文件(下)
- UIVIEW如何设置圆角
- python内置函数 sorted
- UI之CALayer详解
- CentOS5.5+hadoop2.6