824
技术社区[云栖]
挑战淘宝:且看如何用1500行搞定淘宝20000行Java SDK(2)
挑战淘宝:且看如何用1500行搞定淘宝20000行SDK(2)
既然想要比淘宝SDK更优秀,就必须解决淘宝SDK存在的问题,那么来看我是如何设计的:
1)"API请求"(如ItemGetRequest)、"API响应"(如ItemGetResponse)、"API结果"(如Item)本质上都是"数据结构",不需要完成什么具体的操作,因此可以通过XML来进行定义,而不需要在代码中进行定义,这一指导思想是整个设计的核心思想;
2)不同的API请求只是参数不同,因此封装参数为对象;
3)不同的API响应只是属性不同,因此封装属性为对象;由于参数和属性都是"名值对"的操作,因此参数对象和属性对象可以设计为同一个对象:"名值对"对象;
4)设计一种通用的get/set操作,避免大量相似的代码。
来看我的设计的主要的类:
1) TOPApiClient:总的处理类,负责调用API,处理API返回结果;
2) TOPApiResultHandler:负责解析XML文档,生成具体的结果对象TOPApiResult;
3) TOPFactory:根据XML文件生成TOPApiRequest原型和TOPApiResult原型;
4) TOPApiRequest:API请求对象,由TOPFactory创建原型,调用的时候只能进行参数值的设置,不能进行参数设置;
5) TOPApiResult:API返回结果对象,由TOPFactory创建原型,TOPApiResultHandler根据原型进行赋值;由于存在嵌套对象,因此采用装饰者模式进行设计;
6) TOPNameValuePair:名值对对象,用于TOPApiRequest参数设置和TOPApiResult属性设置;
7) TOPBoolPair~TOPFilePair:具体的参数对象,根据不同的类型定义不同的对象,例如TOPBoolPair、TOPIntegerPair、TOPFloatPair、TOPStringPair等;
TOPFactory设计说明:本来也可以不用从XML文件读取定义,而直接在编码的时候边添加参数边赋值参数,但这样做存在如下问题:
1) 依赖编码人员来保证TOPApiRequest和TOPApiResult的正确性,而人与机器相比是最不可靠的,而且不同的人水平不一样,没法做到统一;而由XML文件定义可以通过机器来保证定义正确性,即使错误了,只要查XML文件即可,不需要到代码中一个一个去找;
2) 每次使用TOPApiRequest和TOPApiResult都需要人工添加参数,调用100次就要添加100次,重复代码太多;而由XML文件定义后,只在TOPFactory添加参数,其它地方只要设置参数值即可,不会出现大量重复代码。
TOPNameValuePair设计说明:本来可以全部用"字符串"的形式来保存名值对,但这样做存在两个问题:
1) 所有调用者都必须自己完成特定类型和字符串类型之间的转换,例如int->string或者string->int,因此有100次调用就要转换100次,而直接根据类型分开定义,只需要一次转换即可;
2) 字符串形式无法做静态检查,例如:本来是要设置一个int值,结果错误的赋值为2010xyz,这种情况字符串形式没法检测,而按照类型分开定义则可以完成检测。
我们来看新的设计方案后的样例:public static void main(String[] args) { /*创建TOPApiClient*/ TOPApiClient client = new TOPApiClient(); client.setSession(session); /*创建TOPFactory*/ TOPFactory factory = new TOPFactory(); /*由TOPFactory根据API名称创建API请求request*/ TOPApiRequest request = factory.getTOPApiRequest(“taobao.trades.bought.get”); /*根据参数名称设置API参数*/ request.setApiParameter("status", "TRADE_FINISHED"); /*由TOPFactory根据结果名称创建API结果原型*/ TOPApiResult resultProto = factory.getTOPApiResult(“taobao.trades.bought.get.result”); /*根据结果来生成请求的fields,避免像淘宝SDK那样手工填写*/ request.setApiParameter("fields", resultProto.getChildProto("trade").getApiFields("")); /*运行API*/ int errorCode = client.executeApi(CONST.getCurrentEnv(), request) ; if( errorCode == CONST.TOP_API_ERRCODE_OK){ /*调用成功后,解析XML结果文件,获得最终的结果finalResult*/ TOPApiResult finalResult = client.getResultObject(request.getApiResultFileName(), resultProto); finalResult.printAllFields(""); } else{ System.out.print("Failed to call TOP api, error code is : " + errorCode + "/n"); } }
既然前面已经夸下了海口要比淘宝的SDK更加优秀,那么经过这样的设计后,我们来看看具体优秀在什么地方:
(1)代码量大大减少90%以上
最终代码减少了多少?你可能很难想象:实现XML返回格式只用了不到1200行,即使再加上JSON返回格式,最终不会超过1500行,而淘宝的SDK是22000行!
也许有的朋友可能会说:你的代码量是少了,但XML文件配置工作量就大了!
其实不然,首先一个参数或者一个属性在XML中只需要1行即可,而在淘宝SDK中至少需要7行:1行声明、3行get函数、3行set函数。
再者,修改XML文档比修改Java代码容易得多,而且影响小得多,至少不需要重新编译。
(2)调用更加简单
不管是使用API、还是处理API返回结果、还是获取返回对象,都不再需要关注具体哪个对象、函数名叫什么名字,只需要对照网站上的API相关定义信息即可。
==================淘宝SDK样例==========================
/*淘宝设置不同的参数需要调用不同的函数,不同的参数类型*/
request.setNick(nick);
request.setIid("e9dd57aaa104aa6cf042e3d71421fea9");
=================我的样例================================
/*设置不同的参数调用相同的函数,相同的参数类型*/
request.setApiParameter("nick", "wolf");
request.setApiParameter("iid", "1234567890zxcvbnm");
(3)扩展方便,耦合联动关系小
对于SDK开发者来说,TOP API扩展后,只需要针对新增的API增加XML定义文件即可,不需要开发代码、重新编译、重新发布、重新测试、重新......
对于基于SDK进行二次开发的开发者来说,TOP API扩展后,不需要重新删除jar包,重新编译,然后到SDK中找哪个对象是怎么设计的、对应哪个函数,只需要将新的XML文件放到配置目录中,然后按照老方式开发即可,不需要使用新的函数、熟悉新的参数。
可能有的朋友会担心这样设计性能是否会很差呢?我自己做了简单的测试,样例代码运行100次,需要40秒左右的时间,也就是说平均调用一次只需要0.4秒,而且这0.4秒还有大部分是网络传输耗费的。虽然性能可能比淘宝Java SDK要差,但完全可以满足应用要求。
============================如果需要全套可运行代码,请留言或者发邮件给我========================
最后更新:2017-04-02 04:01:46