使用橋接模式來顯示下單結果
阿新 • • 發佈:2019-09-03
在用工廠方法模式來下不同訂單 中我們看到,我們只簡單顯示來一個“下單成功”,但實際上我們需要給使用者返回到結果可能多種多樣。
先增加一個訂單結果到介面。
public interface OrderSuccessResult { public OrderSuccessResult getResult(Order order); }
新增一個服務訂單結果實現類
@Data @AllArgsConstructor @NoArgsConstructor @Builder public class ServiceOrderSuccessResult implements OrderSuccessResult { privateString content; private String storeName; private String orderCode; private String servicContent; private Date serviceDate; private String storeAddress; private BigDecimal serviceAmount; @Override public OrderSuccessResult getResult(Order order) { ServiceOrderSuccessResult orderSuccessResult = ServiceOrderSuccessResult.builder() .content("服務商家正在稽核,請耐心等待") .orderCode(((ServiceOrder)order).getCode()) .serviceAmount(((ServiceOrder)order).getService().getService().getPrice().getNormalPrice()) .serviceDate(((ServiceOrder)order).getServiceDate()) .servicContent(((ServiceOrder)order).getService().getSimpleContent()) .storeName(((ServiceOrder)order).getStore().getName()) .storeAddress(((ServiceOrder)order).getStore().getAddress().getName()) .build();return orderSuccessResult; } }
給Order介面新增一個適配方法
public interface Order { public void makeOrder(Order order); public OrderSuccessResult getResult(Order order); }
增加一個訂單抽象類,完成對訂單結果介面的橋接
public abstract class AbstractOrder implements Order { protected OrderSuccessResult orderSuccessResult; }
修改各個Order的實現類,繼承於該抽象類
@Data @AllArgsConstructor @NoArgsConstructor @ServiceOrderVersion(value = 1) @RequiredArgsConstructor public class ServiceOrder extends AbstractOrder { 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()); ((ServiceOrder)order).setCode(getCode(idService)); 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); } @Override public OrderSuccessResult getResult(Order order) { this.orderSuccessResult = new ServiceOrderSuccessResult(); return this.orderSuccessResult.getResult(order); } private String getCode(IdService idService) { String flow = String.valueOf(idService.genId()); flow = flow.substring(14,flow.length()); String pre = DateUtils.format(new Date(), DateUtils.pattern9); return pre + flow; } }
我們可以看到this.orderSuccessResult = new ServiceOrderSuccessResult();對ServiceOrderSuccessResult進行了耦合,此處需要修改。
Controller修改如下
@Slf4j @RestController public class OrderController { private ThreadLocal<OrderFactory> orderFactory = new ThreadLocal<>(); private ThreadLocal<Order> orderService = new ThreadLocal<>(); @Autowired private OrderBean orderBean; @Transactional @SuppressWarnings("unchecked") @PostMapping("/makeeorder") public Result<OrderSuccessResult> makeOrder(@RequestBody String orderStr, @RequestParam("type") String type) { log.info(orderStr); Order order = setOrderFactory(orderStr,type); orderService.get().makeOrder(order); return Result.success(orderService.get().getResult(order)); } /** * 判斷是哪一種型別的訂單來獲取哪一種型別的具體訂單工廠 * @param orderStr * @return */ private Order setOrderFactory(String orderStr,String type) { Class<?> classType = orderBean.getOrderMap().get(type); Object order = JSONObject.parseObject(orderStr, classType); // if (orderStr.contains("service")) { // order = JSON.parseObject(orderStr, ServiceOrder.class); // }else if (orderStr.contains("product")) { // order = JSON.parseObject(orderStr, ProductOrder.class); // } Class<?> classFactoryType = orderBean.getOrderFactoryMap().get(type + "Factory"); this.orderFactory.set((OrderFactory) SpringBootUtil.getBean(classFactoryType)); // 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().getOrder()); return (Order) order; } }
現在執行是沒有問題的。返回結果如下
{ "code" : 200 , "data" : { "content" : "服務商家正在稽核,請耐心等待" , "orderCode" : "2019090353318" , "servicContent" : "精細洗車" , "serviceAmount" : 100 , "serviceDate" : "2019-10-03T00:00:00.000+0800" , "storeAddress" : "北京市海淀區西北旺" , "storeName" : "三潤汽修廠" }, "msg" : "操作成功" } 現在我們用簡單工廠進行解耦合。新增版本標籤@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ServiceResultVersion { int value(); }
ServiceOrderSuccessResult打上版本標籤
@Data @AllArgsConstructor @NoArgsConstructor @Builder @ServiceResultVersion(value = 1) public class ServiceOrderSuccessResult implements OrderSuccessResult { private String content; private String storeName; private String orderCode; private String servicContent; private Date serviceDate; private String storeAddress; private BigDecimal serviceAmount; @Override public OrderSuccessResult getResult(Order order) { ServiceOrderSuccessResult orderSuccessResult = ServiceOrderSuccessResult.builder() .content("服務商家正在稽核,請耐心等待") .orderCode(((ServiceOrder)order).getCode()) .serviceAmount(((ServiceOrder)order).getService().getService().getPrice().getNormalPrice()) .serviceDate(((ServiceOrder)order).getServiceDate()) .servicContent(((ServiceOrder)order).getService().getSimpleContent()) .storeName(((ServiceOrder)order).getStore().getName()) .storeAddress(((ServiceOrder)order).getStore().getAddress().getName()) .build(); return orderSuccessResult; } }
新增簡單工廠類(其實這裡也可以使用工廠方法模式,但怕過於複雜,故不使用工廠方法模式)
@Component public class ServiceOrderSuccessResultFactory { @Getter private OrderSuccessResult orderSuccessResult; @PostConstruct private void init() { this.orderSuccessResult = createResult(); } private OrderSuccessResult createResult() { Set<Class<?>> classes = ClassUtil.getClassSet("com.cloud.ownercar.domain"); Object instance = null; try { //過濾有@ServiceResultVersion標籤的類 instance = classes.stream().filter(clazz -> clazz.isAnnotationPresent(ServiceResultVersion.class)) //過濾實現了OrderSuccessResult介面的類 .filter(clazz -> OrderSuccessResult.class.isAssignableFrom(clazz)) //找出版本號大的類,並例項化為物件 .max(Comparator.comparingInt(clazz -> clazz.getAnnotation(ServiceResultVersion.class).value())) .get().newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return (OrderSuccessResult) instance; } }
修改ServiceOrder如下
@Data @AllArgsConstructor @NoArgsConstructor @ServiceOrderVersion(value = 1) @RequiredArgsConstructor public class ServiceOrder extends AbstractOrder { 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()); ((ServiceOrder)order).setCode(getCode(idService)); 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); } @Override public OrderSuccessResult getResult(Order order) { ServiceOrderSuccessResultFactory orderSuccessResultFactory = SpringBootUtil.getBean(ServiceOrderSuccessResultFactory.class); this.orderSuccessResult = orderSuccessResultFactory.getOrderSuccessResult(); return this.orderSuccessResult.getResult(order); } private String getCode(IdService idService) { String flow = String.valueOf(idService.genId()); flow = flow.substring(14,flow.length()); String pre = DateUtils.format(new Date(), DateUtils.pattern9); return pre + flow; }