美文网首页Android架构android 项目开发Android探索之路
MVP架构实现的Github客户端(2-搭建项目框架)

MVP架构实现的Github客户端(2-搭建项目框架)

作者: anly_jun | 来源:发表于2016-07-17 23:37 被阅读3857次

    系列文章:
    1-准备工作
    2-搭建项目框架
    3-功能实现
    4-加入网络缓存

    请先阅读MVP架构实现的Github客户端(1-准备工作). 本文承接上文, 主要介绍项目框架搭建.

    废话少说, 放码过来

    1, 提取一个mvp模块

    提取MVP中View/Presenter相关接口到一个独立的mvp模块(可复用):

    包结构

    mvp_package_structure

    类图

    mvp_class_diagram

    简单说明

    一个MvpView接口来约束View组件:

    public interface MvpView {
    }
    

    MvpPresenter接口中关联MvpView:

    public interface MvpPresenter<V extends MvpView> {
    
    
        /**
         * Set or attach the view to this presenter
         */
        @UiThread
        void attachView(V view);
    
    
        /**
         * Will be called if the view has been destroyed. Typically this method will be invoked from
         * <code>Activity.detachView()</code> or <code>Fragment.onDestroyView()</code>
         */
        @UiThread
        void detachView();
    
    
    }
    

    另外, 由于现在App的内容展示大部分是基于网络数据, 在此扩展了一个通用的LceView, Lce取Loading, Content, Error之意:

    public interface LceView<M> extends MvpView {
    
    
        @UiThread
        public void showLoading();
    
    
        @UiThread
        public void dismissLoading();
    
    
        @UiThread
        public void showContent(M data);
    
    
        @UiThread
        public void showError(Throwable e);
    }
    

    2, 搭建app框架

    包结构

    app框架方面, 个人主张是先基于MVP架构分包 然后根据业务功能划分模块的, 如下:

    app_package_structure

    其中:

    • common

      • 包含util, config, constant等通用包和类.
    • data

      • 包含model, api, db, pref, 网络接口实现等.
      • 其中对外公开一个DataRepository提供业务接口相关数据.
    • di

      • 依赖注入相关的类.
      • 根据dagger2的风格, 一般有module和component模块.
    • presenter

      • 里面根据业务模块划分.
    • ui

      • 包含UI层的所有东东. activity, fragment, widget, dialog, adapter等, 根据需求不同分包方式有出入.

    层次结构

    层次结构相对与业务需求而言, 例如账户相关的登录注册, repo模块相关的repo列表, 详情等...
    大体上每个业务模块都会由以下几个部分构成, 整体的项目层次也是如此:


    mvp_layer

    3, 完善基础工程

    根据上述两步, 一个项目的基本架构已经完成, 但是并不完整, 我们还需要添加一些通用类, 基础类来完善下. 其实这些基类也相当于是一个编码规范, 特别是多人合作项目中, 提前根据项目需求写一些通用类, 工具类, 基类等, 能够避免后续大家编码上各自一套. 所以个人认为这些类的编写也属于搭建框架的一部分.

    添加相关Base类

    为了便于统一处理, 惯例, 我们需要为Activity, Fragment创建一个BaseActivity, BaseFragment. 可以在ui包里创建一个base子包放置.


    base_class

    这个基类好处多多, 例如我们对界面的统一处理, 生命周期的日志打印, 添加统计工具等, 都能很方便的再基类里面处理.

    封装相关工具类

    上文所说, 个人习惯对第三方开源库再做一层封装, 以便后续灵活替换.
    使用过程中, 也只需调用封装后的接口即可, 无需关注具体的依赖包. 也利于大家协作统一.
    例如:

    1. Logger封装
      创建一个AppLog类来包装Logger:
    public class AppLog {
    
        private static final String TAG = "GithubApp";
    
        /**
         * initialize the logger.
         */
        public static void init() {
            Logger.init(TAG);
        }
    
        /**
         * log.i
         * @param msg
         */
        public static void i(String msg) {
            if (BuildConfig.DEBUG) {
                Logger.i(msg);
            }
        }
    
        /**
         * log.d
         * @param msg
         */
        public static void d(String msg) {
            if (BuildConfig.DEBUG) {
                Logger.d(msg);
            }
        }
    
        /**
         * log.w
         * @param msg
         */
        public static void w(String msg) {
            if (BuildConfig.DEBUG) {
                Logger.w(msg);
            }
        }
    
        /**
         * log.e
         * @param msg
         */
        public static void e(String msg) {
            Logger.e(msg);
        }
    }
    
    1. 图片加载库封装
      封装一个ImageLoader工具类来对外提供接口加载图片:
    public class ImageLoader {
    
        /**
         * Load image from source and set it into the imageView. Use Glide now.
         * @param context context.
         * @param source could be Uri/String/File/ResourceId.
         * @param view the imageView.
         */
        public static void load(Context context, Object source, ImageView view) {
            Glide.with(context)
                    .load(source)
                    .centerCrop()
                    .into(view);
        }
    }
    

    Dagger相关基础类

    因为我们使用的Dagger2来做依赖注入, 因为Activity和Application的Context是比较常用的, 我们会构建Activity, Application相关的component/module来提供对应的Context.
    具体代码参看github工程源码.

    4, 整体结构

    假设我们的产品需要是迭代式的, 至此, 我们的基础框架已经差不多了(不建议做过多过早设计).
    回顾下, 大体结构现在基本如下:

    mvp

    mvp

    app

    app

    具体代码请参看https://github.com/mingjunli/GithubApp

    目前代码只是一个基础的框架, 心急的同学可以参看这个工程, 架构类似. 一个简单的新闻客户端, 用来做MVP demo的.

    相关文章

      网友评论

      • 60b1e550c17d:过度封装反而画蛇添足,难免产生过多限制,依项目而定
      • 叫我稻草人:对于新手很多学习的地方,持续关注 :grin:
      • 提丶米:很不错
        anly_jun:@提丶米 谢谢 :smile:
      • 不浪费一个字节:博主有github相关的api文档吗?如果可以的话,我也来贡献分力量搭建一个完整的客户端
        anly_jun:@ad78915300ff 使用标准的github api, https://developer.github.com/v3/
      • 十条可怜:写的好棒,忍不住评论了。能学到不少呢
        anly_jun:@十条可怜 谢谢, 共同学习~
      • starCoder:不错,我之前也搭了一个类似的基础框架,不过没用rxjava 没用注入,而是使用了注解
        68768b474bfc:@anly_jun Context用AppComponent注入是否有必要,context可以从Application对象中取吧。还有在实际开发中,哪些对象推荐用dagger注入。
        十条可怜:@anly_jun 你好,我有一个地方不明白,请教一下。在你的源码中,Retorfit和OKHttpClient并未用Component关联起来,是如何实现注入的呢?
        anly_jun:@star_code Rx和Dagger注入渐渐流行起来, 可以学习下~ :smile:
      • 墨小痕92:可以参考clean架构,分层更清晰
        anly_jun:@TellH 是的, 所以说架构只是一种思想, 是看合适不合适~. 同样是MVP, 实现的方式也可以是不同的.
        68768b474bfc:@anly_jun 我也觉得Mvp够用了,如果m层和p层再加一层或再抽象成接口就很麻烦了
        anly_jun:@答非所問 个人认为Clean架构有点偏重, 快速移动开发并不是特别适用 :smile:
      • a738e9bd3d17:写的不错,我感觉还应该再加一层UserCase,这样就把数据与业务完全隔离开了
        anly_jun:@ad78915300ff 是的, 相对于移动开发来说, 特别是现在产品基本是快速迭代, 快速试错, 推倒重来的玩法. 过于复杂的架构是不太合适的~
        不浪费一个字节:@anly_jun 哪个太繁琐了,没必要,本来mvp就已经繁琐了
        anly_jun:@小伙挺帅 可以参考下Bob大叔的The Clean Architecture, 个人觉得作为移动开发来说有点过于繁重.

      本文标题:MVP架构实现的Github客户端(2-搭建项目框架)

      本文链接:https://www.haomeiwen.com/subject/addpjttx.html