之前一个月负责对接的一些工作,公司业务系统中有要和第三方平台合作的情况,而且将要对接的第三方还不止一家,并且未来可能更多,但业务流程相对固定,创建订单->成功回调,取消订单,获取订单轨迹等。其中创建订单、取消订单 与轨迹获取是必有的过程,而且是我方主动发起的请求,因为订单可能发给不同的对接公司,所以如果是采用常规用if()else()来做代码应该是这样
如果后续再新接入一家,那么还要再加上一个else if(),首先这违背了开闭原则。
仔细分析,无论是向哪个公司发送创建订单的请求,它只不过是业务中的一个环节,业务中不必关注要向哪个合作方发送,业务走到这步只需要告诉我要创建订单即可,因此这里可以巧妙的采用监听模式来解决,
首先在业务环节注册一个监听,当业务执行到这里向所有监听者发送消息,监听者拿到消息后判断是否是自己所负责的公司,如果是则处理并创建订单,如果不是则直接返回。
接口代码如下
其中一个实现类
调用处代码
这样设计之后可以避免新增对接方后对原有业务代码的改动。
像接口调用这样的业务,一般对方接口要求的信息比较多,如果每个调用方法都自己组织请求参数就避免不了请求报文缺胳膊少腿这种现象,此时使用建造者模式能够帮助我们避免这种情况。
这样可以稳定建造过程,保证需要的地方一个不少。
if(标识为a公司){
a公司接口数据组织发送
}else if(标识为b公司){
b公司接口数据组织发送
}
如果后续再新接入一家,那么还要再加上一个else if(),首先这违背了开闭原则。
仔细分析,无论是向哪个公司发送创建订单的请求,它只不过是业务中的一个环节,业务中不必关注要向哪个合作方发送,业务走到这步只需要告诉我要创建订单即可,因此这里可以巧妙的采用监听模式来解决,
首先在业务环节注册一个监听,当业务执行到这里向所有监听者发送消息,监听者拿到消息后判断是否是自己所负责的公司,如果是则处理并创建订单,如果不是则直接返回。
接口代码如下
public interface CommonRequest {
public String creatOrder(int code,CommonParam param);
public String cancelOrder(int code,CommonParam param);
public String trackOrder(int code,CommonParam param);
}
其中一个实现类
@Service
public class SFRequest implements CommonRequest{
private static Logger logger = LoggerFactory.getLogger(SFRequest.class.getName());
@Value("${dev_id}")
private long dev_id ;//appid
@Value("${dev_key}")
private String dev_key ; //appkey
public static final int CODE=2;
public static Gson gson=new Gson();
private static String path="http://openic.sf-express.com";
/**
* 创建订单
*/
@Override
public String creatOrder(int code,CommonParam param) {
if(code==CODE){
CreateMain sfparam=ParamBuilder.buildCreateObject(param);
CommonParam cp = new CommonParam();
try {
BeanUtils.copyProperties(cp, sfparam);
} catch (IllegalAccessException | InvocationTargetException e1) {
String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e1);
logger.error(fullStackTrace);
}
String sign = SingMaker.generateSign(cp, dev_id, dev_key);
sfparam.setSign(sign);
logger.info("请求顺丰订单创建接口发送数据为"+gson.toJson(sfparam));
if(sfparam!=null){
try {
String result = HttpClientUtil.sendPostJSONDataNoURLEncoder(path+"/open/api/external/createorder",gson.toJson(sfparam));
logger.info("请求顺丰订单创建接口返回数据为"+result);
return result;
} catch (Exception e) {
String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e);
logger.error(fullStackTrace);
}
}
}
return null;
}
/**
* 取消订单
*/
@Override
public String cancelOrder(int code, CommonParam param) {
if(code==CODE){
CancleAndTrackMain sfparam=ParamBuilder.buildCancleObject(param);
CommonParam cp = new CommonParam();
if(sfparam!=null){
try {
BeanUtils.copyProperties(cp, sfparam);
String sign = SingMaker.generateSign(cp, dev_id, dev_key);
sfparam.setSign(sign);
logger.info("请求顺丰订单取消接口发送数据为"+gson.toJson(sfparam));
String result = HttpClientUtil.sendPostJSONDataNoURLEncoder(path+"/open/api/external/cancelorder",gson.toJson(sfparam));
logger.info("请求顺丰订单取消接口返回数据为"+result);
return result;
} catch (Exception e) {
String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e);
logger.error(fullStackTrace);
}
}
}
return null;
}
/**
* 获取订单轨迹
*/
@Override
public String trackOrder(int code, CommonParam param) {
if(code==CODE){
CancleAndTrackMain sfparam=ParamBuilder.buildTrackObject(param);
CommonParam cp = new CommonParam();
if(sfparam!=null){
try {
BeanUtils.copyProperties(cp, sfparam);
String sign = SingMaker.generateSign(cp, dev_id, dev_key);
sfparam.setSign(sign);
String result = HttpClientUtil.sendPostJSONDataNoURLEncoder(path+"/open/api/external/ridertrack",gson.toJson(param));
return result;
} catch (Exception e) {
String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e);
logger.error(fullStackTrace);
}
}
}
return null;
}
}
调用处代码
@Service
public class RequestService {
@Autowired
List<CommonRequest> regist;
public String createOrder(int code,CommonParam commonParam) {
String result=null;
for(CommonRequest request:regist){
result = request.creatOrder(code,commonParam);
if(result!=null){
return result;
}
}
return result;
}
public String cancleOrder(int code,CommonParam commonParam) {
String result=null;
for(CommonRequest request:regist){
result = request.cancelOrder(code,commonParam);
if(result!=null){
return result;
}
}
return result;
}
public String track(int code,CommonParam commonParam) {
String result=null;
for(CommonRequest request:regist){
result = request.trackOrder(code,commonParam);
if(result!=null){
return result;
}
}
return result;
}
}
这样设计之后可以避免新增对接方后对原有业务代码的改动。
像接口调用这样的业务,一般对方接口要求的信息比较多,如果每个调用方法都自己组织请求参数就避免不了请求报文缺胳膊少腿这种现象,此时使用建造者模式能够帮助我们避免这种情况。
public static CreateMain buildCreateObject(CommonParam param) {
CreateMain object = makeMainPart(param);
// 装配收货人
if (object == null) {
return null;
}
makeReceive(object, param);
//装配店铺信息
makeShopPart(object, param);
// 装配案件详情
makeOrderDetail(object, param);
// 装配产品详情
makeProductDetail(object, param);
makeInvoice(object, param);
return object;
}
这样可以稳定建造过程,保证需要的地方一个不少。