挑战淘宝:且看如何用1500行搞定淘宝20000行Java SDK(1)
挑战淘宝:且看如何用1500行搞定淘宝20000行Java SDK
继亚马逊、雅虎、Google等一众知名大公司掀起了开放API的潮流后,淘宝也不甘寂寞,于2009推出了TOP平台,搭上了这趟开放API的顺风车(详细请看https://open.taobao.com/)。
为了更好的开发TOP程序,淘宝提供了各种语言的SDK,其中自然少不了编程语言老大Java的SDK。但不幸的是,当我兴致勃勃的将SDK下载下来,准备大干一场的时候,却发现淘宝的Java SDK只是“看上去很美”,用起来却很不爽。
让我们分析淘宝给的样例来看看究竟是什么不爽。
如下是淘宝给的API调用样例(详见:https://wiki.open.taobao.com/index.php/FAQ): public class ApiDemoTest { protected String testUrl = "https://gw.api.tbsandbox.com/router/rest"; protected String appkey = "test"; protected String secret = "test"; protected String nick="alipublic01"; protected String sessionID = "alipublic01"; protected TaobaoJsonRestClient jsonclient; public ApiDemoTest() throws TaobaoApiException { /*第一步:创建一个TaobaoJsonRestClient对象,此对象负责完成TOP API调用*/ jsonclient = new TaobaoJsonRestClient(testUrl,appkey, secret); } } public void testItemGet() throws TaobaoApiException{ /*第二步:生成一个API请求对象,如ItemGetRequest */ ItemGetRequest request = new ItemGetRequest(); /*第三步:设置API调用参数,如setFields、setNick、setIid*/ request.setFields("iid,num,price,input_pids,product_id,sku.sku_id ,title,outer_id ,props"); request.setNick(nick); request.setIid("e9dd57aaa104aa6cf042e3d71421fea9"); /*第四步:获得一个API响应对象,如ItemGetResponse,此对象由TaobaoJsonRestClient调用API请求对象request生成*/ ItemGetResponse response = jsonclient .itemGet(request,sessionID,nick); System.out.println(response.getBody()); }
我们基于这个样例来看淘宝Java SDK的调用机制:
1) 创建一个TaobaoJsonRestClient对象,此对象负责完成TOP API调用
2) 生成一个API请求对象:ItemGetRequest,设置API调用参数
3) 获得一个API响应对象:ItemGetResponse,此对象由TaobaoJsonRestClient生成
4) 从ItemGetResponse中通过TaobaoItemJSONConvert获取最终的对象;
从样例来看,淘宝的SDK调用机制也没有什么问题:采用面向对象,请求和响应隔离。不过如果你打开SDK的源代码、或者亲自调用几个API体验一下,就会发现淘宝SDK中的实现机制存在如下问题:
1)绝大部分代码是非常相似、非常简单的属性定义和操作
API相关的类有:请求类、响应类、结果类、转换类,但不同的API这些类都非常类似,都是属性定义、属性get/set操作。我们来看源代码(由于代码太多,省略了绝大部分相似的代码):
==========================================
Item结果类:
public class Item extends TaobaoModel{ private static final long serialVersionUID = 33230486742413888L; private String iid; …………………………………..... (此处省略约70行属性定义)………. private File image; public String getIid() { return iid; } public void setIid(String iid) { this.iid = iid; } ……………………………………(此处省略约300行get/set函数)……………………………… public File getImage() { return image; } public void setImage(File image) { this.image = image; }
=====================================================================
Trade类:
public class Trade extends TaobaoModel { private static final long serialVersionUID = -8410518683112517552L; private String sellerNick; …………………………………………… (此处省略约150行属性定义)………. private Boolean is3D; public String getSellerNick() { return sellerNick; } public void setSellerNick(String sellerNick) { this.sellerNick = sellerNick; } ……………………………………(此处省略约500行get/set函数)……………………………… public Boolean getIs3D() { return is3D; } public void setIs3D(Boolean is3D) { this.is3D = is3D; }
2)设计与实现没有分离,每个API都要设计4个不同的类,导致代码量非常庞大
我们以SDK的样例来进行分析,分析内容请看代码注释:public void testItemGet() throws TaobaoApiException{ /*调用不同的API,必须new不同的API对象 *例如如果要获取交易数据,则要这样写: *TradeGetRequest request = new TradeGetRequest() */; ItemGetRequest request = new ItemGetRequest(); /*调用不同的API,必须调用此API特有的设置函数进行参数设置。 *例如ItemGetRequest有setIid函数,TradeGetRequest有setTid函数,无法通过通用的 *方法来设置API参数 */ request.setFields("iid,num,price,input_pids,product_id,sku.sku_id ,title,outer_id ,props"); request.setNick(nick); request.setIid("e9dd57aaa104aa6cf042e3d71421fea9"); /*此处代码有几个问题: *1)调用不同的API,必须调用此API特有的响应函数进行处理 * 例如如果要获取交易数据,必须使用TradeGetResponse对象 *2)每个结果对象,jsonclient都必须有一个对应的get函数,例如Item对象是itemGet * 函数, Trade对象是tradeGet函数 *3)在每个get函数里面,又会有不同的Converter对象来负责从JSON或者XML文档 * 转换为对象:TaobaoItemJSONConvert(转换为Item对象) 和 * TaobaoTradeJSONConvert(转换为Trade对象) */ ItemGetResponse response = jsonclient .itemGet(request,sessionID,nick); System.out.println(response.getBody()); }
用代码统计工具统计,代码量是21296行代码;加上大部分代码相似,很难阅读。
3)API的任何变更,SDK都必须更新,开发者也必须相应更新,耦合联动关系很强
例如:ItemGetRequest的setIid修改为setIID,那么所有使用了setIid的地方都必须修改,然后重新编译。
又如:如果在SDK2.0中某个API增加一个参数,或者增加了新的API,而你又必须使用的话,那么就必须切换到SDK2.0,这个切换可不是改个名字或者增删一行代码那么简单,你需要将原来的jar包删除,然后倒入新的jar包,然后再到SDK2.0中找到对应的API,还要寄希望于淘宝不要把其它API相关对象的定义给改了。
加上淘宝有的代码并没有开放,如果一旦出问题,调试和修改几乎不可能的。基于这些原因,我决定自己动手建立一套比淘宝SDK更简单、更容易理解和使用的调用机制。
==========================未完待续,欲知如何设计,请看下回分解================
最后更新:2017-04-02 04:01:45