需求:
物流系统要新增包裹数据,现在物流的上游有三种包裹:线上的包裹,线下的包裹,外部的包裹,每种包裹在新增时会有些不同的操作,比如线上线下的包裹新增后要发消息给订单履约中心方便监控,线上包裹新增时要判断包裹是否需要抽检,钉箱,并生成相关的数据等。
每种包裹都有其特殊的操作,从系统维护的角度上说,可以使用策略模式来新增包裹,方便后期的维护,如果后期线上包裹需要多一些操作,那只改线上包裹的新增策略即可,测试也只用回归线上包裹。
当然对于三种包裹公共的部分,需要放到一个公共类里,统一维护。
代码:
代码结构:
1.写一个策略模版的接囗:PackageSyncStrategy
/**
* 包裹同步策略
*/
public interface PackageSyncStrategy {
/**
* 策略类型
* @return
*/
abstract OrderTypeEnum getStrategy();
/**
* 创建包裹数据
* @param packageDTO
*/
ResultDTO syncPackageInfo(TransportPackageDTO packageDTO);
}
TransportPackageDTO是一个包裹类,
ResultDTO是一个结果的封装类,可替换成自己公司的结果类,或者替换成String,Boolean都可以。
针对策略类型还可以再封装一个接囗:BaseStrategy,使其更通用(别的地方可能也会用到策略模式),例如
public interface BaseStrategy<T> {
/**
* 匹配实现策略
* @return
*/
T getStrategy();
}
然后改写上面的策略模版PackageSyncStrategy:
/**
* 包裹同步策略
*/
public interface PackageSyncStrategy extends BaseStrategy<OrderTypeEnum> {
/**
* 创建包裹数据
* @param packageDTO
*/
ResultDTO syncPackageInfo(TransportPackageDTO packageDTO);
}
是不是更简洁了
其中枚举:OrderTypeEnum(根据自己的业务来创建时映枚举,我们的包裹是从订单维度来区分的,而且只分了三种)
public enum OrderTypeEnum {
ONLINE_ORDER(0,"线上订单"),
OFFLINE_ORDER(1,"线下订单"),
OUTER_ORDER(2,"外部订单");
@Getter
private Integer type;
@Getter
private String desc;
OrderTypeEnum(Integer type, String desc) {
this.type = type;
this.desc = desc;
}
}
2.开始写各种包裹的新增策略(具体逻辑省略,打了一句日志代替了):
a.线上包裹新增策略:
/**
* 线上包裹同步策略
*/
@Slf4j
@Service
public class OnlinePackageSyncStrategy implements PackageSyncStrategy {
@Override
public OrderTypeEnum getStrategy() {
return OrderTypeEnum.ONLINE_ORDER;
}
@Override
public ResultDTO syncPackageInfo(TransportPackageDTO packageDTO) {
log.info("线上包裹新增数据开始");
return ResultDTO.succeed();
}
}
b.线下包裹新增策略:
/**
* 线下包裹同步策略
*/
@Slf4j
@Service
public class OfflinePackageSyncStrategy implements PackageSyncStrategy {
@Override
public OrderTypeEnum getStrategy() {
return OrderTypeEnum.OFFLINE_ORDER;
}
@Override
public ResultDTO syncPackageInfo(TransportPackageDTO packageDTO) {
log.info("线下包裹新增数据开始");
return ResultDTO.succeed();
}
}
c.外部包裹新增策略:
/**
* 外部包裹包裹同步策略
*/
@Slf4j
@Service
public class OuterPackageSyncStrategy implements PackageSyncStrategy {
@Override
public OrderTypeEnum getStrategy() {
return OrderTypeEnum.OUTER_ORDER;
}
@Override
public ResultDTO syncPackageInfo(TransportPackageDTO packageDTO) {
log.info("外部包裹新增数据开始");
return ResultDTO.succeed();
}
}
3.最后编写测试类:
public class PackageCreateTest extends BaseTest{
@Autowired
private List<PackageSyncStrategy> packageSyncStrategies;
@Test
public void testPack() {
TransportPackageDTO packageDTO = TransportPackageDTO.builder().orderType(OrderTypeEnum.OFFLINE_ORDER).build();
if(CollectionUtils.isEmpty(packageSyncStrategies)) {
log.warn("匹配不到新增包裹的同步策略::packageInfoSyncStrategies was empty");
return ;
}
Optional<PackageSyncStrategy> optional = packageSyncStrategies.stream()
.filter(o -> o.getStrategy().equals(packageDTO.getOrderType()))
.findFirst();
if(!optional.isPresent()) {
log.warn("匹配不到订单类型为{}的包裹数据同步策略", packageDTO.getOrderType().getType());
return ;
}
ResultDTO resultDTO = optional.get().syncPackageInfo(packageDTO);
log.info("新增包裹的结果:"+resultDTO);
}
}
这里看不懂的多看看就明白了
4.运行结果:
线下包裹新增数据开始
新增包裹的结果:ResultDTO(model=null, success=true, errorCode=0, errorMsg=null)