挑战淘宝:且看如何用1500行搞定淘宝20000行Java SDK
继亚马逊、雅虎、Google等一众知名大公司掀起了开放API的潮流后,淘宝也不甘寂寞,于2009推出了TOP平台,搭上了这趟开放API的顺风车(详细请看http://open.taobao.com/)。
为了更好的开发TOP程序,淘宝提供了各种语言的SDK,其中自然少不了编程语言老大Java的SDK。但不幸的是,当我兴致勃勃的将SDK下载下来,准备大干一场的时候,却发现淘宝的Java SDK只是“看上去很美”,用起来却很不爽。
让我们分析淘宝给的样例来看看究竟是什么不爽。
如下是淘宝给的API调用样例(详见:http://wiki.open.taobao.com/index.php/FAQ#SDK):
}
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 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 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的样例来进行分析,分析内容请看代码注释:
/*调用不同的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更简单、更容易理解和使用的调用机制。
==========================未完待续,欲知如何设计,请看下回分解================