閱讀835 返回首頁    go 阿裏雲 go 技術社區[雲棲]


挑戰淘寶:且看如何用1500行搞定淘寶20000行Java SDK(1)

         挑戰淘寶:且看如何用1500行搞定淘寶20000行Java SDK

繼亞馬遜、雅虎、Google等一眾知名大公司掀起了開放API的潮流後,淘寶也不甘寂寞,於2009推出了TOP平台,搭上了這趟開放API的順風車(詳細請看https://open.taobao.com/)。

為了更好的開發TOP程序,淘寶提供了各種語言的SDK,其中自然少不了編程語言老大JavaSDK。但不幸的是,當我興致勃勃的將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行代碼;加上大部分代碼相似,很難閱讀。 

3API的任何變更,SDK都必須更新,開發者也必須相應更新,耦合聯動關係很強

例如:ItemGetRequestsetIid修改為setIID,那麼所有使用了setIid的地方都必須修改,然後重新編譯。

又如:如果在SDK2.0中某個API增加一個參數,或者增加了新的API,而你又必須使用的話,那麼就必須切換到SDK2.0,這個切換可不是改個名字或者增刪一行代碼那麼簡單,你需要將原來的jar包刪除,然後倒入新的jar包,然後再到SDK2.0中找到對應的API,還要寄希望於淘寶不要把其它API相關對象的定義給改了。

 

    加上淘寶有的代碼並沒有開放,如果一旦出問題,調試和修改幾乎不可能的。基於這些原因,我決定自己動手建立一套比淘寶SDK更簡單、更容易理解和使用的調用機製。

==========================未完待續,欲知如何設計,請看下回分解================

 

最後更新:2017-04-02 04:01:45

  上一篇:go QColor與Int類型相互轉換
  下一篇:go major=$(awk "//$2= =/"$module/" {print //$1}" /proc/devices)正確理解。