API 接口返回数据结构的思考

返回数据结构的讨论已经过去一两周了,这两天看代码有更清晰的认识。可以拿来回顾一下。

方式一:

API 返回数据之前一直是以对象不同,通过不同字段来区分的。就是大括号,暂且称为方式一,

"data": {
        "token": "...",
        "expires_in": 2592000,
        "user_id": "fca61e32-f22a-11e8-9465-02420a000008",
        "user_info": {...},
        "user_times": {...},
        "levels": [...]
    }



方式二

直到有新同事提出了新的方案。使用 数组来放置不同对象。。 好处是对顺序有调整有更灵活的适应。添加新的数据类型对原 API 没有影响(这一点老的组织方式一样有,稍后讨论。)。

"data": [
            {
            "type": "title",
            "label_name": "Newest"
            ...
            },
            {
             "id": 514,
             "type": "article",
             ...
            }
            ....
     ]

接收处理

1, 在定义 Bean 类的数量上,两者并没有任何差别。差别主要在根节点数据属性的数量上。

  • 方式一每个 bean 类只要定义自己的属性就行了。 方式二需要额外定义一个类,包含了所有属性值。

比较带来的好处与处理

1. 数据类型的类型。

方式1 接收到数据类型,通过现有的映射就能映射为相应的对象。而方式二则不是,只能映射成一个包含所有属性的对象。想要获得不同对象,按照zhaonan 的说法,只要强转就行了。然而事实并不是这么美好。

- 类型转换的思想是:向上转型(从子类转为父类)是安全的,向下转型是危险的,除非明确知道是子类对象,只是引用是父类的。所以 java 中有 `instanceof` 来用于转型之前先判断。但是,方式二生成的就是父类对象。是判断不出子类的。所以为了区分不同对象,需要再硬编码 new 对象,转换对象。 ***我觉着这个地方是整个方案中最丑陋的部分,也是反对使用这种方案的主要原因***
    private void updateList(NewArticleBean.Data data) {
        switch (data.type) {
            case "title":
                TitleBean titleBean = new TitleBean();
                titleBean.labelName = data.labelName;
                titleBean.type = data.type;
                itemList.add(titleBean);
                break;
            case "top":
                TopFirstBean topFirstBean = new TopFirstBean();
                topFirstBean.type = data.type;
                topFirstBean.id = data.id;
                topFirstBean.slug = data.slug;
                topFirstBean.title = data.title;
                topFirstBean.metaDesc = data.metaDesc;
                topFirstBean.description = data.description;
                topFirstBean.imgName = data.imgName;
                TopFirstImage image = new TopFirstImage();
                image.large.img = data.imagelist.large.img;
                image.large.width = data.imagelist.large.width;
                image.large.height = data.imagelist.large.height;
                image.medium.img = data.imagelist.medium.img;
                image.medium.width = data.imagelist.medium.width;
                image.medium.height = data.imagelist.medium.height;
                image.small.img = data.imagelist.small.img;
                image.small.width = data.imagelist.small.width;
                image.small.height = data.imagelist.small.height;
                image.tiny.img = data.imagelist.tiny.img;
                image.tiny.width = data.imagelist.tiny.width;
                image.tiny.height = data.imagelist.tiny.height;
                topFirstBean.authorId = data.authorId;
                topFirstBean.authorName = data.authorName;
                topFirstBean.reviewed = data.reviewed;
                topFirstBean.order = data.order;
                topFirstBean.shareCount = data.shareCount;
                topFirstBean.viewCount = data.viewCount;
                topFirstBean.syncOnlineServer = data.syncOnlineServer;
                topFirstBean.syncTestServer = data.syncTestServer;
                topFirstBean.createdAt = data.createdAt;
                topFirstBean.updatedAt = data.updatedAt;
                topFirstBean.formatDate = data.formatDate;
                itemList.add(topFirstBean);
                break;
            case "article":
                ArticleBean articleBean = new ArticleBean();
                articleBean.type = data.type;
                articleBean.id = data.id;
                articleBean.slug = data.slug;
                articleBean.title = data.title;
                articleBean.metaDesc = data.metaDesc;
                articleBean.description = data.description;
                articleBean.imgName = data.imgName;
                TopFirstImage image1 = new TopFirstImage();
                image1.large.img = data.imagelist.large.img;
                image1.large.width = data.imagelist.large.width;
                image1.large.height = data.imagelist.large.height;
                image1.medium.img = data.imagelist.medium.img;
                image1.medium.width = data.imagelist.medium.width;
                image1.medium.height = data.imagelist.medium.height;
                image1.small.img = data.imagelist.small.img;
                image1.small.width = data.imagelist.small.width;
                image1.small.height = data.imagelist.small.height;
                image1.tiny.img = data.imagelist.tiny.img;
                image1.tiny.width = data.imagelist.tiny.width;
                image1.tiny.height = data.imagelist.tiny.height;
                articleBean.authorId = data.authorId;
                articleBean.authorName = data.authorName;
                articleBean.reviewed = data.reviewed;
                articleBean.order = data.order;
                articleBean.shareCount = data.shareCount;
                articleBean.viewCount = data.viewCount;
                articleBean.syncOnlineServer = data.syncOnlineServer;
                articleBean.syncTestServer = data.syncTestServer;
                articleBean.createdAt = data.createdAt;
                articleBean.updatedAt = data.updatedAt;
                articleBean.formatDate = data.formatDate;
                itemList.add(articleBean);
                break;
            case "category":
                CategoryBean categoryBean = new CategoryBean();
                categoryBean.id = data.id;
                categoryBean.type = data.type;
                categoryBean.name = data.name;
                categoryBean.slug = data.slug;
                categoryBean.image = data.image;
                categoryBean.imageSmall = data.imageSmall;
                categoryBean.description = data.description;
                categoryBean.topic_count = data.topic_count;
                categoryBean.parent = data.parent;
                categoryBean.order = data.order;
                categoryBean.createdAt = data.createdAt;
                categoryBean.updatedAt = data.updatedAt;
                itemList.add(categoryBean);
                break;
        }
    }

相反,使用方式一,想要转化为 list 的方式则优雅很多

    List dataList = new ArrayList(); // 新生成一个列表
    // 将原有不同对象放到列表中,已经是详细的对象。
    dataList.add(data.getHeader());
    dataList.addAll(data.getArticles());
    ...

2. 对象的清晰和结构清晰

方式二的处理方式所有的属性都在一个对象中,无论是结构和占用内存上,都不占优势。特别是在调试过程中,一大片属性都是空的,需要根据不同的 type 的值,去自己分析这个对象有哪些属性,其他无用属性的扰乱,非常不清晰。

3. 顺序调整

方式二最大的有点就是能够应对排序的调整,如果排序调了,可以不用改一行代码就能实现了排序。

针对这一点,我想说的是,不同类型的数据,调换位置的可能性非常小。如果这个不同类型的数据带有调整顺序,完全可以通过添加 order 属性解决。

4. 添加新对象不对影响老的接口

这一点上方式二并不占优势。 两种方式添加新的对象都不会影响老的接口。方式一根本不会讲新的字段实例化成为对象。而方式二会将json 示例化为对象,但却没有一点用处,浪费了资源。

总结

在几点比较中,只有顺序改变能够带来一点好处。其他方面,数组的组织方式并没有带来任何的方便之处,反而使处理更加麻烦,结构更加混乱。

results matching ""

    No results matching ""