搭建高质量的Android项目框架系列三

1.分包
1.1.首先是其架构,是按功能模块进行划分的,但不必分得太细,最多五个模块就够了,很多类按其功能其实可以属于多个模块,这个时候就需要抽出来。
1.2.类定义要明确,权责单一

这里写图片描述

2.详解
2.1.模型层定义了所有的模型
2.2.接口层封装了服务器提供的API
2.3.核心层处理所有业务逻辑
2.4.界面层就处理界面的展示

接口层
1.接口层封装了网络底层的API,并提供给核心层调用
1.1.PostEngine,请求引擎类,对请求的发送和响应结果进行处理;PostEngine将请求封装好发送到服务器,并对响应结果的json数据转化为Response对象返回Response其实就是响应结果的json数据实体类,json数据是有固定结构的,分为三类,如下:

        {"event": "0", "msg": "success"}
        {"event": "0", "msg": "success", "obj":{...}}
        {"event": "0", "msg": "success", "objList":[{...}, {...}], "currentPage": 1, "pageSize": 20, "maxCount": 2, "maxPage": 1}

1.1.1event为返回码,0表示成功
1.1.2.msg则是返回的信息
1.1.3.obj是返回的单个数据对象
1.1.4.objList是返回的数据对象数组
1.1.5.currentPage表示当前页
1.1.6.pageSize则表示当前页最多对象数量
1.1.7.maxCount表示对象数据总量
1.1.8.maxPage表示总共有多少页

1.2.Response,响应类,封装了Http请求返回的数据结构;
根据以上结构,Response基本的定义如下:

        public class Response<T> {
            private String event;
            private String msg;
            private T obj;
            private T objList;
            private int currentPage;
            private int pageSize;
            private int maxCount;
            private int maxPage;

            //getter和setter方法
            ...    
        }

每个属性名称都要与json数据对应的名称相一致,否则无法转化。obj和objList用泛型则可以转化为相应的具体对象了。

1.3.Api,接口类,定义了所有的接口方法;

        public Response<Void> login(String loginName, String password);
        public Response<VersionInfo> getLastVersion();
        public Response<List<Coupon>> listNewCoupon(int currentPage, int pageSize);
1.4.ApiImpl,接口实现类,实现所有Api接口方法。
    @Override
    public Response<Void> login(String loginName, String password) {
        try {
            String method = Api.LOGIN;
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("loginName", loginName));
            params.add(new BasicNameValuePair("password", EncryptUtil.makeMD5(password)));
            TypeToken<Response<Void>> typeToken = new TypeToken<Response<Void>>(){};
            return postEngine.specialHandle(method, params, typeToken);
        } catch (Exception e) {
            //异常处理
        }
    }

实现中将请求参数和返回的类型定义好,调用PostEngine对象进行处理。

核心层
核心层介于接口层和界面层之间,主要处理业务逻辑,集中做数据处理。向上,给界面层提供数据处理的接口,称为Action;向下,调用接口层向服务器请求数据。

1.向上的Action中定义的方法类似如下:

public void getCustomer(String loginName, CallbackListener callbackListener);

这是一个获取用户信息的方法,因为需要向接口层请求服务器Api数据,所以添加了callback监听器,在callback里对返回的数据结果进行操作。CallbackListener就定义了一个成功和一个失败的方法,代码如下:

    public interface CallbackListener<T> {
        /**
         * 请求的响应结果为成功时调用
         * @param data  返回的数据
         */
        public void onSuccess(T data);

        /**
         * 请求的响应结果为失败时调用
         * @param errorEvent 错误码
         * @param message    错误信息
         */
        public void onFailure(String errorEvent, String message);
}

接口的实现基本分为两步:
1)参数检查,检查参数的合法性,包括非空检查、边界检查、有效性检查等;
2)使用异步任务调用接口层的Api,返回响应结果。

需要注意的是,Action是面向界面的,界面上的数据可能需要根据不同情况调用不同的Api。后续扩展可以在这里添加缓存,但也要视不同情况而定,比如有些变化太快的数据,添加缓存就不太适合了。

界面层
1.界面层处于最上层,其核心就是负责界面的展示
2.界面层package的定义我也并不按照旧版的功能模块划分,而根据不同类型划分,这个地方是有待商榷的,其实也是可以在内部进一步细化

这里写图片描述

3.其中,activity、adapter、fragment各自都有一个基类,做统一的处理,比如定义了一些共用的常量、对象和方法等,界面层是最复杂,最容易变得混乱不堪,最容易出问题的层级。所以,从架构到代码,很多东西都需要设计好,以及规范好,才能保证程序易维护、易扩展。

4.如果需要为不同商户定制不同app的需求,Android Studio可以通过设置Gradle,不同app可以添加不同的productFlavors。

模型层
1.模型层横跨所有层级,封装了所有数据实体类,基本上也是跟json的obj数据一致的,在接口层会将obj转化为相应的实体类,再通过Action传到界面层。

2.另外,模型层还定义了一些常量,比如用户状态、支付状态等。在Api里返回的是用1、2、3这样定义的,而我则用枚举类定义了这些状态。用枚举类定义,就可以避免了边界的检查,同时也更明了,谁会记得那么多1、2、3都代表什么状态呢。然而用枚举类定义的话,就必须能将1、2、3转化为相应的枚举常量。这里,我提供两种实现方式:

2.1.使用gson的@SerializedName标签,比如0为FALSE,1为TRUE,通过gson的方式,直接访问TRUE或FALSE就会自动序列化为1或0;可以如下定义:

    public enum BooleanType {
        @SerializedName("0")
        FALSE,
        @SerializedName("1")
        TRUE
}

2.2.通过定义一个value,因为没有序列化,则需要通过getValue方式获取1或0如下:

public enum BooleanType {
        FALSE("0"),
        TRUE("1");

        private String value;

        BooleanType(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }
}

更多建议
1. 如何让应用层代码合理的解耦内聚?
无论是iOS的controller还是android的activity,都容易变成fat MVC。怎么样找到一种方式去拆分这部分代码很重要。如果一个工程师能清楚的知道他每一个函数该放到哪一个类,这样应用层才好维护。 关于这一块有很多成熟的方案了,mvc,mvvm,mvp等等,但这些是方案,细节还需要架构师自己敲定。

2.要有清晰的data flow:
一个app说到底是关于data的变化和展现。从用户输入采集数据,上报服务器,加工再展示。这个流程能不能在你的架构里看出清晰的data flow很重要。工程师在遇到bug的时候第一反应是查数据是不是出了问题,头脑里有data flow就能快速的定位问题。

参考文档:
https://www.zhihu.com/question/27645587
http://keeganlee.me/post/android/20150605
http://blog.csdn.net/luyi325xyz/article/details/43482123
http://blog.csdn.net/luyi325xyz/article/details/43085409

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值