背景
一直在做业务系统的开发,相同的业务操作可能会存在多个不同的场景。比如计算上班的交通花费,步行、自驾、打车、公共交通肯定花费不同,如果直接写 if-else 的话,代码可读性会很差,而且难以扩展,随着场景的增加和复杂度提升,使得代码更加难以维护。所以最好的方式是抽象出来一个接口,各个场景单独实现内部的业务逻辑,把差异单独开。那么问题来了,如何根据业务参数来实现不同业务场景的服务自动切换呢?
实现
在网上冲浪查了一下,基本上就是参考文章里写的那四种,个人比较倾向于最后一种,代码简洁性和扩展性都比较好。目前使用的也是这种,记录一下实现方式。其实还是觉得有点麻烦,后面再看看能不能优化改进一下~
/**
* 根据业务场景抽象出来的接口
*
* @author 8102
* @date 2020/7/31
*/
public interface ICostService {
/**
* 根据业务场景标记
*/
void register();
/**
* 计算花费
* @param request 计算参数
*/
void computer(Request request);
}
/**
* 自驾方式花费计算服务
*
* @author 8102
* @date 2020/7/31
*/
@Slf4j
@Service
public class SelfDrivingServiceImpl implements ICostService {
@Override
@PostConstruct
public void register() {
CostComputerServiceBroker.register("SelfDriving", this);
}
@Override
public void computer(Request request) {
// 计算
}
}
/**
* 花费计算策略类
*
* @author 8102
* @date 2020/7/31
*/
@Slf4j
@Service
public class CostComputerServiceBroker {
/**
* 服务集合
*/
private static Map<String, ICostService> serviceMap = new HashMap<>();
/**
* 标记服务
* @param serviceKey 服务标记
* @param service 服务实例
*/
public static void register(String serviceKey, ICostService service) {
CostComputerServiceBroker.serviceMap.put(serviceKey, taskApprovalService);
}
/**
* 花费计算
* @param request 参数
*/
public void computerCost(Request request) {
ICostService service = getService(request.getServiceKey());
service.computer(taskApproveRequest);
}
/**
* 获取服务
* @param serviceKey 业务场景Key
* @return
*/
private ICostService getService(String serviceKey) {
ITaskApprovalService service = taskApprovalServiceMap.get(serviceKey);
if (Objects.isNull(service)) {
throw new SystemException(String.format("serviceKey[%s]未匹配到对应服务", serviceKey));
}
return service;
}
}