相信设计模式大家在学的时候或多或少会学一些,但学完估计就忘了。那么在开发业务代码的时候能否用到呢。接下来我说一下我们这边业务开发场景,以及分享下我们是怎么落地这块业务需求的。
业务需求描述:需要对外提供一个数据上传接口,需要上传的数据类型会有很多种。
初期实现:针对每一个数据写一份CRUD样板代码。这样我需要对外提供的接口随着数据数目增加而增加。
优化方法:这里可以利用策列模式来优化代码。
具体落地步骤
第一、定义一个上传数据的接口
/**
* 数据上传接口
*/
public interface UploadService {
/**
* 数据上传接口
*
* @param jsonObject
*/
void upload(JSONObject jsonObject);
}
第二步、定义这些接口的实现类
@Service("whole")
public class WholesaleTransactionContractServiceImpl implements WholesaleTransactionContractService, UploadService {
@Autowired
private WholesaleTransactionContractMapper wholesaleTransactionContractMapper;
@Resource
private RocketMsgSendService rocketMsgSendService;
@Override
public void upload(JSONObject jsonObject) {
WholesaleTransactionContract wholesaleTransactionContract = JSON.toJavaObject(jsonObject, WholesaleTransactionContract.class);
wholesaleTransactionContractMapper.insert(wholesaleTransactionContract);
// 拼接数据组装消息体
jsonObject.put("id", wholesaleTransactionContract.getId());
// 发送消息
rocketMsgSendService.sendAsyncMsg(jsonObject);
}
}
第三步、定义一个策略模式 上下文
@Component
public class UploadStrategyContext {
private final Map<String, UploadService> uploadStrategyMap =
new ConcurrentHashMap<>(4);
public UploadStrategyContext(Map<String, UploadService> uploadStrategyMap) {
this.uploadStrategyMap.clear();
uploadStrategyMap.forEach((k, v) -> this.uploadStrategyMap.put(k, v));
}
public UploadService getService(JSONObject jsonObject) {
UploadService uploadService = uploadStrategyMap.get(jsonObject.getString("type"));
Assert.notNull(uploadService, "type值不正确,请查看接口文档中对应的type的描述");
return uploadService;
}
}
第四步、定义controller
@PostMapping("/uploadData")
public String uploadData(@RequestBody JSONObject jsonObject) {
log.info("上传的数据为:{}", jsonObject);
UploadService service = context.getService(jsonObject);
service.upload(jsonObject);
return "上传成功";
}
大家看改造后的代码就非常灵活了,不管后面来什么类型的数据controllor对应接口都不用添加了。唯一需要做的就是写接口的实现类。
这样做也符合java提倡的对修改关闭,对扩展开放的原则。