专栏首页算法之名用工厂方法模式来下不同订单 顶

用工厂方法模式来下不同订单 顶

现在假设我们有两种类型的订单,汽车服务订单和商城配件订单

我们的抽象订单接口为

public interface Order {
    public void makeOrder(Order order);
}

抽象订单工厂接口为

public interface OrderFactory {
    public Order createOrder();
}

现有具体的汽车服务类型订单

@Data
@AllArgsConstructor
@NoArgsConstructor
@ServiceOrderVersion(value = 1)
@RequiredArgsConstructor
public class ServiceOrder implements Order {
    private Long id;
    @NonNull
    private String code;
    @NonNull
    private Store store;
    @NonNull
    private ProviderService service;
    @NonNull
    private Car car;
    @NonNull
    private Date serviceDate;
    @NonNull
    private String contact;
    @NonNull
    private String contactTel;
    private AppUser user;
    @NonNull
    private String content;
    private int status;
    private Date createDate;


    @Override
    public void makeOrder(Order order) {
        ServiceOrderDao serviceOrderDao = SpringBootUtil.getBean(ServiceOrderDao.class);
        IdService idService = SpringBootUtil.getBean(IdService.class);
        ((ServiceOrder)order).setId(idService.genId());
        AppUser loginAppUser = AppUserUtil.getLoginAppUser();
        AppUser user = new AppUser();
        user.setId(loginAppUser.getId());
        user.setUsername(loginAppUser.getUsername());
        ((ServiceOrder)order).setUser(user);
        ((ServiceOrder)order).setStatus(1);
        ((ServiceOrder)order).setCreateDate(new Date());
        serviceOrderDao.save((ServiceOrder) order);
    }
}

@ServiceOrderVersion版本号如下

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ServiceOrderVersion {
    int value();
}

商城配件订单略

具体汽车服务工厂,我们将其注入Spring容器,不需要每次下单的时候都去扫描包

@Component
public class ServiceOrderFactory implements OrderFactory {
    private Set<Class<?>> classes = ClassUtil.getClassSet("com.cloud.ownercar.domain");

    @Override
    public Order createOrder() {
        Object instance = null;
        try {
            //过滤有@OrderVersion标签的类
            instance = classes.stream().filter(clazz -> clazz.isAnnotationPresent(ServiceOrderVersion.class))
                    //过滤实现了Order接口的类
                    .filter(clazz -> Order.class.isAssignableFrom(clazz))
                    //找出版本号大的类,并实例化为对象
                    .max(Comparator.comparingInt(clazz -> clazz.getAnnotation(ServiceOrderVersion.class).value()))
                    .get().newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return (Order) instance;
    }
}

具体配件工厂略

Controller如下,用传递的内容来判断是哪种类型的订单,并给抽象订单工厂来获取具体的订单工厂,通过具体的订单工厂来生成订单服务,完成下单功能。考虑到线程安全问题,所以要加ThreadLocal进行保护。

@Slf4j
@RestController
public class OrderController {
    private ThreadLocal<OrderFactory> orderFactory = new ThreadLocal<>();
    private ThreadLocal<Order> orderService = new ThreadLocal<>();

    @Transactional
    @SuppressWarnings("unchecked")
    @PostMapping("/makeeorder")
    public Result<String> makeOrder(@RequestBody String orderStr) {
        log.info(orderStr);
        Order order = setOrderFactory(orderStr);
        orderService.get().makeOrder(order);
        return Result.success("下单成功");
    }

    /**
     * 判断是哪一种类型的订单来获取哪一种类型的具体订单工厂
     * @param orderStr
     * @return
     */
    private Order setOrderFactory(String orderStr) {
        Order order = null;
        if (orderStr.contains("service")) {
            order = JSON.parseObject(orderStr, ServiceOrder.class);
        }else if (orderStr.contains("product")) {
            order = JSON.parseObject(orderStr, ProductOrder.class);
        }
        if (order instanceof ServiceOrder) {
            this.orderFactory.set(SpringBootUtil.getBean(ServiceOrderFactory.class));
        }else if (order instanceof ProductOrder) {
            this.orderFactory.set(SpringBootUtil.getBean(ProductOrderFactory.class));
        }
        orderService.set(orderFactory.get().createOrder());
        return order;
    }
}

dao,mapper略

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 设计模式整理 顶

    Iterator模式可以帮助我们分离具体的集合跟遍历,就是在代码中更换了集合,也可以不需要重新调用新集合的方法。

    算法之名
  • RabbitMQ使用多路由,多队列来破除流控

    流控机制是我们在使用RabbitMQ最头疼的问题,一旦并发激增时,消费者消费队列消息就像滴水一样慢。

    算法之名
  • 使用桥接模式来显示下单结果 顶

    在用工厂方法模式来下不同订单 中我们看到,我们只简单显示来一个“下单成功”,但实际上我们需要给用户返回到结果可能多种多样。

    算法之名
  • 聊聊skywalking的spring-annotation-plugin

    本文主要研究一下skywalking的spring-annotation-plugin

    codecraft
  • Dagger2系列——初识

    经过一段时间的纠结和水深火热,终于渐渐领悟了Dagger2,在此分享一下学习心得,希望同样对Dagger2水深火热的你们有点帮助。

    蜻蜓队长
  • Java开发小技巧_02

    jeremyxu
  • SpringBoot系列教程之Bean加载顺序之错误使用姿势辟谣

    在网上查询 Bean 的加载顺序时,看到了大量的文章中使用@Order注解的方式来控制 bean 的加载顺序,不知道写这些的博文的同学自己有没有实际的验证过,本...

    猿天地
  • SpringBoot系列教程之Bean加载顺序之错误使用姿势辟谣

    在网上查询 Bean 的加载顺序时,看到了大量的文章中使用@Order注解的方式来控制 bean 的加载顺序,不知道写这些的博文的同学自己有没有实际的验证过,本...

    一灰灰blog
  • apache的开源项目-模板引擎(Velocity)_学习了两天就上手啦_源码下载

    首先,如果你对Velocity不是很了解,还是建议你去apache的官方网站上去走走....

    Hongten
  • 全文搜索实战2-ik分词及搜索高亮

    数据存储功能基于mybatisplus框架,实现相关entity和mapper等即可。

    技术路漫漫

扫码关注云+社区

领取腾讯云代金券