SDK的设计
来源:互联网 发布:网络直播招聘 编辑:程序博客网 时间:2024/06/05 03:38
代码仅提供参考,已去掉业务内容,下载地址:http://download.csdn.net/detail/hel_wor/9596946
考虑:
1.请求方式2.请求函数简洁直观3.合理利用java/C#的类型推导4.request,response对象的设计,考虑接口,抽象类带来的隐式多继承5.服务异常,网络异常的封装
解决:
1:一般采用http请求的方式。请求url,请求体,请求头的构造,content-type,accept-type视后端服务而定。2:请求方法应当简单明了,复杂的请求过程应当被封装,只暴露简单的接口。3:能够做到类型自动推导的,不要让调用者使用强制转换或显式的声明请求以及返回对象类型--使用泛型。4:为适应扩展性,当开放更多的请求接口后能不改动请求代码结构的情况下扩展请求及响应对象--使用接口,抽象类。
由于之前是做C#的,所以这次公司的开放平台C#版本SDK由本人编写。
一.请求方式采用http:
a:根据url创建httpwebrequest;
b:设置消息头;
c:设置消息体;
d:发送请求获取响应;
e:处理响应;
请求的构造:
/// <summary> /// 请求头 /// </summary> /// <param name="contentLength">内容长度</param> /// <returns>HttpWebRequest</returns> private void SetRequestHeader(int contentLength) { httpRequest.Method = request.GetMethod(); httpRequest.KeepAlive = true; httpRequest.ProtocolVersion = HttpVersion.Version10; httpRequest.ContentType = "application/x-www-form-urlencoded"; httpRequest.ContentLength = contentLength; httpRequest.Timeout = this.timeout * 1000; } /// <summary> /// 请求体 /// </summary> /// <returns>请求体</returns> private string SetRequestBody() { Dictionary<string, string> requestParams = request.GetParamMap(); //// 表单提交方式,构造post请求体内容 return WebHelper.GetPostBody(requestParams); } /// <summary> /// 获取响应 /// </summary> /// <returns>响应信息</returns> public HttpWebResponse GetResponse() { byte[] requestByte = Encoding.UTF8.GetBytes(this.SetRequestBody()); SetRequestHeader(requestByte.Length); try { using (Stream requestStream = httpRequest.GetRequestStream()) { requestStream.Write(requestByte, 0, requestByte.Length); } } catch (Exception e) { throw new WinxuanApiException(e.Message); } return (HttpWebResponse)httpRequest.GetResponse(); }
响应的处理:
/// <summary> /// 获取响应内容并做处理 /// </summary> /// <param name="t">请求</param> /// <returns>响应内容</returns> public T GetResponse(WinxuanHttpRequest<T> t) { string result = string.Empty; using (HttpWebResponse httpResponse = t.GetResponse()) { if (httpResponse.StatusCode == HttpStatusCode.OK) { using (StreamReader readStream = new StreamReader(httpResponse.GetResponseStream(), Encoding.UTF8)) { result = readStream.ReadToEnd(); } } else { throw new WinxuanApiException("API请求响应的状态码:" + httpResponse.StatusCode); } result = JObject.Parse(result)["response"].ToString(); T baseResponse = JsonConvert.DeserializeObject<T>(result); if (!baseResponse.isSuccess()) { throw new WinxuanApiException(baseResponse.ResultCode.ToString(), baseResponse.ErrorMsg, baseResponse.ResultMessage); } return baseResponse; } }
二:保证扩展性所以使用接口,抽象类。
Request对象的定义:
namespace Winshare.Distribute.Sdk.Model{ public interface IWinXuanRequest { string GetApiPath(); string GetMethod(); Dictionary<string, string> GetParamMap(); }}
namespace Winshare.Distribute.Sdk.Model{ public abstract class BaseRequest<T> : IWinXuanRequest where T : BaseResponse { protected string REQUEST_TOKEN = "/oauth2/authorize"; protected string ACCESS_TOKEN = "/oauth2/accessToken"; protected string REFRESH_TOKEN = "/oauth2/refreshToken"; //业务部分接口地址省略 public abstract string GetMethod(); public abstract string GetApiPath(); public abstract Dictionary<string, string> GetParamMap(); }}
需要扩展的请求类都需要继承BaseRequest< T >类,并重写我们要求继承者实现的3个抽象方法。
Response对象的定义:
namespace Winshare.Distribute.Sdk.Model{ public abstract class BaseResponse { /// <summary> /// 请求处理成功返回true,请求处理失败返回false。 /// </summary> [JsonProperty("result")] private bool result; /// <summary> /// 状态码 /// </summary> [JsonProperty("result_code")] private int resultCode; //// 部分属性省略 //// get,set方法省略
需要扩展的响应对象都需要继承BaseResponse类。
三.使用泛型做到类型自动推导
C#和Java都能利用泛型做到类型感知,自动推导,以下针对C#:
暴露给第三方使用的sdk接口:
namespace Winshare.Distribute.Sdk.Interact{ public interface IWinxuanClient { T execute<T>(BaseRequest<T> t) where T : BaseResponse; }}
C#的泛型,如果类型参数多于1个,即使是相同类型的两个类型参数T,在使用泛型接口时都需要显式的声明两个参数的类型。所以把响应类型放在了请求类型中,而未采用下面的定义方式:
U execute<T, U>(T t) where T : BaseRequest<U> where U : BaseResponse;
最终的请求方式为:
AccessTokenResponse accessTokenResponse = client.execute(request);
而非:
AccessTokenResponse accessTokenResponse = client.execute<AccessTokenRequest ,AccessTokenResponse >(request);
使用泛型让我们无需强制转换,使用单个泛型参数让我们无需显式声明泛型类型,这是因为泛型在编译期间会推导类型信息。
0 0
- SDK的设计
- SDk初始化的设计参考
- 基于Atinav SDK的UPnP设计
- 浅谈sdk的开发与设计
- iOS SDK的设计与实现
- 教你快速高效接入SDK——SDK接入抽象层的设计
- JavaScript SDK 设计指南
- 架构设计(重业务:后期制作不同业务的sdk)
- Android sdk开发(二) Log日志类的设计
- Android应用性能监测sdk的设计与实现
- Android多线程下载SDK的设计,支持断点续传
- Sdk迭代开发设计需要考虑的方面总结
- Unity3d Android SDK接入解析(二)Unity3d Android SDK的设计与两种接入方式
- 使用SDK设计linux应用程序
- 自定义可复用统计SDK设计
- [我帮新浪来改错]新浪微博SDK中AsyncWeiboRunner的诡异设计
- 安卓中文SDK连载(2) 软件的设计要求
- ccflow 驰骋工作流引擎的共享任务,应用背景,设置,设计,sdk接口
- Spark Streaming + Kafka 另一利器 Kafka-spark-consumer 项目
- UART接口
- 建造者模式(Builder)及其应用
- 面向对象相关知识点总结
- Java8大排序算法-冒泡排序
- SDK的设计
- hdu5802Windows 10(贪心+dfs)
- EM-最大期望算法
- 个人学习_Android MVP
- gdb相关
- RedHat 5下安装oracle netca找不到命令
- Linux驱动程序中的file,inode,file_operations三大结构体
- JDK与Tomcat环境变量的配置
- 插件开发之360 DroidPlugin源码分析(二)Hook机制