用工廠方法模式來下不同訂單
阿新 • • 發佈:2019-09-02
現在假設我們有兩種型別的訂單,汽車服務訂單和商城配件訂單
我們的抽象訂單介面為
public interface Order { public void makeOrder(Order order); }
抽象訂單工廠介面為
public interface OrderFactory { public Order createOrder(); }
現有具體的汽車服務型別訂單
@Data @AllArgsConstructor @NoArgsConstructor @ServiceOrderVersion(value = 1) @RequiredArgsConstructorpublic 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 privateString 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; } }