设计模式之观察者模式(监听模式)与建造者模式在实际开发种的巧用

之前一个月负责对接的一些工作,公司业务系统中有要和第三方平台合作的情况,而且将要对接的第三方还不止一家,并且未来可能更多,但业务流程相对固定,创建订单->成功回调,取消订单,获取订单轨迹等。其中创建订单、取消订单 与轨迹获取是必有的过程,而且是我方主动发起的请求,因为订单可能发给不同的对接公司,所以如果是采用常规用if()else()来做代码应该是这样
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;
	}


这样可以稳定建造过程,保证需要的地方一个不少。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值