1. 程式人生 > >使用橋接模式來顯示下單結果

使用橋接模式來顯示下單結果

用工廠方法模式來下不同訂單 中我們看到,我們只簡單顯示來一個“下單成功”,但實際上我們需要給使用者返回到結果可能多種多樣。

先增加一個訂單結果到介面。

public interface OrderSuccessResult {
    public OrderSuccessResult getResult(Order order);
}

新增一個服務訂單結果實現類

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
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; } }

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