1.功能需求
业务上需要对所有的店铺进行店铺的校验,店铺订单的拉取,店铺产品的拉取,店铺单个产品的更新等处理动作。
2.第一版思路
第一时间拿到这个需求的时候首先想到的思路是,想消除if/else.所以首先就想通过工厂的形式来消除。
3.第一版具体代码思路
3.1 首先我们建立一个接口
public interface PullShopNameOrderService {
/**
* 拉取订单
* @param shopify
*/
void pullShopNameOrder(Shopify shopify);
}
3.2 第二步我们将每个店铺类型都对此接口进行实现
某个实现类的示例
@Service
public class PullShopifyShopNameOrderImpl implements PullShopNameOrderService {
@Resource
private ShopifyOrderService shopifyOrderService;
@Override
public void pullShopNameOrder(Shopify shopify) {
ShopifyJobDTO shopifyJobDTO = new ShopifyJobDTO();
shopifyJobDTO.setShopName(shopify.getShopName());
shopifyJobDTO.setShopifyOrderStatus(shopify.getState());
shopifyOrderService.getShopifyOrderUpdateTime(shopifyJobDTO);
}
}
3.3 第三步我们建立一个工厂
public class PullShopNameOrderFactory {
static Map<String, PullShopNameOrderService> pullShopNameOrderMap = new HashMap<>();
static {
pullShopNameOrderMap.put(StoreTypeEnum.shopify.name(), SpringContextUtil.getBean(PullShopifyShopNameOrderImpl.class));
pullShopNameOrderMap.put(StoreTypeEnum.yampi.name(), SpringContextUtil.getBean(PullYampiShopNameOrderImpl.class));
pullShopNameOrderMap.put(StoreTypeEnum.cartpanda.name(), SpringContextUtil.getBean(PullCartPandaShopNameOrderImpl.class));
pullShopNameOrderMap.put(StoreTypeEnum.woocommerce.name(), SpringContextUtil.getBean(PullWoocomShopNameOrderImpl.class));
pullShopNameOrderMap.put(StoreTypeEnum.nuvemshop.name(),SpringContextUtil.getBean(PullNuvemShopNameOrderImpl.class));
}
public static Optional<PullShopNameOrderService> getPullShopNameOrderType(String type){
Optional<PullShopNameOrderService> pullShopNameOrder = Optional.ofNullable(pullShopNameOrderMap.get(type));
return pullShopNameOrder;
}
}
这里我们建立了一个工厂,然后将实现类全部由这个工厂进行管理,以后我们只要增加哪种类型的店铺就可以直接在map里面增加。
注明:上面put的时候看到我使用了SpringContextUtil.getBean这个方法,是因为实现类里面注入了别的service。所以我需要将实现类这个bean也交由spring管理,那么我们就需要在实现类上加上注解@Service。
这个时候这个Bean就交由spring管理了,那么在工厂里面我们需要put的就是由容器管理的Bean。
思考:如果我不用SpringContextUtil.getBean,直接new PullShopifyShopNameOrderImpl()放入进去会发生什么问题
4.业务实现类
@Override
public void pullShopNameOrder(String shopifyId,String shopifyOrderStatus) {
Object result = redisUtil.get(CachePrefix.PULL_ORDER_ID.getPrefix() + shopifyId);
if(ObjectUtils.isNotNull(result)){
throw new ServiceException("该店铺已经拉取过订单,请20分钟后再点击拉取");
}
Shopify shopify = this.getOne(new LambdaQueryWrapper<Shopify>().eq(Shopify::getShopifyId, shopifyId).eq(Shopify::getDeleteFlag, false));
if (ObjectUtils.isNull(shopify)){
throw new ServiceException("无此店铺");
}
String type = shopify.getType();
if (StringUtils.isBlank(type)){
throw new ServiceException("此店铺请先确认属于那个平台");
}
redisUtil.set(CachePrefix.PULL_ORDER_ID.getPrefix() + shopifyId,shopifyId,60*20);
PullShopNameOrderService pullShopNameOrder = PullShopNameOrderFactory.getPullShopNameOrderType(type).orElseThrow(() -> new ServiceException("无此类型店铺"));
shopify.setState(shopifyOrderStatus) ;
threadPoolTaskExecutor.execute(()->pullShopNameOrder.pullShopNameOrder(shopify));
}
结尾:到这里就结束了,只要后续传入的是哪个类型的店铺,就只要去工厂里面取就可以了
消除了根据类型来判断的代码,让代码更可读
疑问:如果说还需要对店铺进行检验,拉取产品之类的,那么这个方式还适用吗?