我司通道服务里调用的一个三方服务商,其响应结构如下:
字段名 | 类型 | 描述 |
---|---|---|
code | int | 业务响应的 code 码(非 HTTP 状态码) |
msg | string | 返回值的状态描述 |
data | obj | 业务数据,具体字段参考各 API 接口返回值 |
这个标准化响应格式,大家都比较熟悉。正常响应时,code=200,并将数据结果放到data
里。非正常响应时,code是非200的错误码,data为空。
错误响应示例:
{"code": 400, "msg": "手机号格式不正确"}
{"code":404,"data":null,"msg":"订单不存在"}
正确响应示例:
{
"code": 200,
"data": {
"orderId": "ORD20250720001",
"status": "已支付",
"amount": 299.00
},
"msg": "订单查询成功"
}
{"code":200,"msg":"用户签约成功"}
与之对应,我们程序里定义了相应的模型类:
@Data
public class SanHeCommonResponse implements Serializable {
/** 业务响应的code 码(非HTTP 状态码) */
private Integer code;
/** 返回值的状态描述 */
private String message;
/** 业务数据,具体的字段内容参考各个API 接口的返回值 */
private T data;
// 判断响应是否成功(code为200时表示成功)
public boolean isSuccess(){
return code == 200;
}
}
execute
方法及实现三方服务API对接层中,我们将数据加密/签名、http通信、验签/数据解密等通用性功能封装在底层,见下面的execute
方法如下。注意,后面我们重点要谈针对这个方法的重构。
/**
* 安**宇服务商接口通信(含请求及响应)封装
*/
public static SanHeCommonResponse execute(NewSanHeApiEnum apiEnum, String token) {
SanHeCommonRequest requestBody = new SanHeCommonRequest();
requestBody.setNonceStr(RandomUtil.randomString(10));
requestBody.setData...
JSONObject requestParams = JSON.parseObject(JSON.toJSONString(requestBody));
HttpEntity
execute
方法返回值重构OOP程序设计的一个重要思想是明确对象的职责。
针对这种三方服务对接的需求场景,我们需要把握好一个设计理念:将三方服务调用涉及的数据加密/签名、http通信、验签/数据解密等通用性功能封装在底层,使上层的接口处理方法专注于接口数据的逻辑处理。
这个execute
方法在返回值方面存在的问题是:调用方需要通过SanHeCommonResponse.data
获取并转换为实际业务数据,这增加了编码成本。
SanHeCommonResponse response = execute(API_ORDER, token);
if (!response.isSuccess()) {
throw new BizException("查询失败");
}
OrderResponse data = JSON.parseObject(response.getData().toString(), OrderResponse.class);
针对返回值方面的这个问题,重构结果如下:
/**
* 安**宇服务商接口通信(含请求及响应)封装
*/
public static T SanHeCommonResponse execute(NewSanHeApiEnum apiEnum, String token, Class clazz) {
...
SanHeCommonResponse sanHeCommonResponse = JSON.parseObject(body, new TypeReference>(){});//用`new TypeReference>(){}`来解析带有泛型的响应, 避免IDE类型转换警告。
if (!sanHeCommonResponse.isSuccess()) {
throw BizException.build(sanHeCommonResponse.getCode(), sanHeCommonResponse.getMessage());
}
return Optional.ofNullable(sanHeCommonResponse.getData())
.orElse(new JSONObject())
.toJavaObject(clazz);
}
这时,上层调用直接一行代码搞定:
OrderResponse data = execute(API_ORDER, token, OrderResponse.class);
重构的目的是使方法更通用,能够直接返回业务数据对象,而不是整个SanHeCommonResponse
对象。通过使用泛型,让调用者可以指定期望返回的业务数据类型,将类型安全性提前至编译期,有效增强程序健壮性。
当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!--buguge
本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/buguge/p/19005338
参与评论
手机查看
返回顶部