策略+工厂模式 ------让代码更可读

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));
    }

 结尾:到这里就结束了,只要后续传入的是哪个类型的店铺,就只要去工厂里面取就可以了

消除了根据类型来判断的代码,让代码更可读

疑问:如果说还需要对店铺进行检验,拉取产品之类的,那么这个方式还适用吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值