前段时间做项目时有用到一个比较常用的设计模式-MVP模式,我个人比较喜欢有优美的结构的代码,我始终相信代码也是一种艺术,现在就特地将这一部分拿出来分享哈,自己也可以再熟悉熟悉。
OK,废话不多说先上个图,来看看我的代码中MVP模式的应用:

  • View 代表的是Android中对应的Activity,Fragment或View等与UI相关的。(view通常含有Presenter的引用)
  • ViewInterface 用来提取一些可重用的功能,比如Pregress等以及方便的更改View,类之间更加的模块化。使用时,只需要让View去实现这个接口.
  • Presenter 相当于一个路由,又来自View的转发请求,以及Model回调的数据实体。(Presenter持有Model层的应用,以及ViewInterface的引用)
  • Model 业务逻辑层。提取数据从Database,或云端API,缓存等,然后再对数据加以处理,再分发给Presenter去处理。

    OK,来个栗子看看。一个根据图书的isbn,从豆瓣的RestFul API中提取图书的细节信息,再返回给前台界面。

1.在View层中

/** * ViewInterface * 定义一些通用的view接口 */public interface LoadDataView {    /***     * 耗时操作,加载数据,显示Progress     */    void showLoading();    /***     * 隐藏Progress     */    void hideLoading();}
/** * 更细小的,用来显示图书细节的View接口 */public interface LoadBookView extends LoadDataView {    void showDetailsView(BookEntity entity);}
/*** * Fragment,属于View层,实现了ViewInterface(LoadBookView) */public class BookDetailFragment extends Fragment implements LoadBookView{    /**图书条形码ISBN号*/    public static final String ISBN = "9787121060748";    /**持Presenter对象*/    private BookDetailsPresenter presenter;    @Override    public void onActivityCreated(Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);        initWidget();        presenter = new BookDetailsPresenter(getActivity(), ISBN); // 实例化一个presenter对象        presenter.setView(this); //让Presenter持一个ViewInterface实例(LoadBookView)        presenter.loadData(); //告诉Presenter快给我加载Data    }         @Override    public void showDetailsView(BookEntity entity) {        //更新UI等操作    }    @Override    public void showLoading() {        rlProgress.setVisibility(View.VISIBLE);    }    @Override    public void hideLoading() {        rlProgress.setVisibility(View.GONE);    }}

2.在Presenter层中

public class BookDetailsPresenter {    /**持一个Model层的对象,用来从网页接口Rest Api中提取数据*/    private RestApi restApi = null;    /**一个ViewInterface对象,用来回调Data给View*/    private LoadBookView loadBookView;    private String isbn;    public BookDetailsPresenter(Context context, String isbn) {        restApi = new RestApiImpl(context);        this.isbn =isbn;    }    public void setView(LoadBookView loadBookView) {        this.loadBookView = loadBookView;    }    public void loadData() {        loadBookView.showLoading();        //耗时操作,开个线程异步的加载数据        Thread thread = new Thread(new Runnable() {            @Override            public void run() {                restApi.getBookDetailByIsbn(isbn, bookDetailsCallback);            }        });        thread.start();    }    //匿名内部类,接收bookDetailCallback的回调数据    private RestApi.BookDetailsCallback bookDetailsCallback = new RestApi.BookDetailsCallback() {        @Override        public void onBookEntityLoaded(BookEntity bookEntity) {            notifyDataLoadedSuccessful(bookEntity);            BookDetailsPresenter.this.loadBookView.hideLoading();        }        @Override        public void onError(Exception e) {            //异常后的相关处理        }    };    /***    * 通知获取数据成功了,赶快通知UI更新吧    */    private void notifyDataLoadedSuccessful(final BookEntity bookEntity) {        Handler handler = new Handler(Looper.getMainLooper());        handler.post(new Runnable() {            @Override            public void run() {                BookDetailsPresenter.this.loadBookView.showDetailsView(bookEntity);            }        });    }  }

3.在Model层中

/**** 整个应用程序需要的数据实体类*/public class BookEntity {    //一些set,get方法}/** * 一个接口,用来从rest api api获得数据,它的实现在RestApiImpl中 */public interface RestApi {    String API_ISBN_BASE_URL = "https://api.douban.com/v2/book/isbn/";    /***    * 更细小的接口,用来将获取到的数据,回调给它的调用者    */    interface BookDetailsCallback {        void onBookEntityLoaded(BookEntity bookEntity);        void onError(Exception e);    }    /**     * 从网络获取数据,然后通过bookDetailCallback回调给Presenter     * @param isbn     * @param bookDetailsCallback     */    void getBookDetailByIsbn(final String isbn, final BookDetailsCallback bookDetailsCallback);}

好了核心的代码就贴到这儿了,每个类关键的地方都偶注释,整个Demo的代码在github上,有兴趣可以下来看看。有不好的地方也多多指正,感谢万分!

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. “罗永浩抖音首秀”销售数据的可视化大屏是怎么做出来的呢?
  3. Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
  4. 不吹不黑!GitHub 上帮助人们学习编码的 12 个资源,错过血亏...
  5. Android(安卓)定位服务
  6. Android(安卓)万能适配器 节省你的开发时间
  7. Android(安卓)应用程序启动过程分析 (用SysTrace 跟踪分析)
  8. Android自动接听和挂断电话实现原理
  9. Android实现应用程序卸载自己

随机推荐

  1. Android中的资源与国际化!
  2. Android(安卓)VCard通讯录导入导出详解
  3. [置顶] Android之高仿手机QQ聊天
  4. 网络界面Android(安卓)网络连接--Wifi/3G
  5. Android中Intent的显示和隐式使用
  6. Android之WebView优化之路
  7. Android自定义控件一简介
  8. 《第一行代码》学习笔记一
  9. android软键盘的用法总结
  10. Android(安卓)wifi驱动的移植 realtek 81