【設計模式工程實踐】裝飾器模式記錄對訂單管理的操作日誌

hikeboy發表於2020-10-31

裝飾器模式:
對目標類的功能進行增強,但是又不想去直接修改原來的類的程式碼,因為一旦修改就得重新測試這個類,違背“對擴充套件開放,對修改關閉”的原則。
另外,有的時候想增強的類是別人給的jar包,你想修改也沒法修改

此時,就可以上裝飾器模式。

裝飾器模式有一些非常經典的實現

(1)比如java的io體系,可以一層包裝一層,一層包裝一層,外面的一層,都會對立面的一層進行功能的增強。
(2)還有就是spring的aop,aop這塊可以基於動態代理的理念,裝飾我們的目標物件,然後加入事務控制,日誌列印之類的功能。

需求:

已經開發完了訂單管理模組OrderStateManager,但是想對訂單的任何操作都有個日誌記錄留痕。此時不要去修改原來的類,而是對OrderStateManager進行裝飾增強。

package com.zhss.eshop.order.state;

import com.zhss.eshop.order.domain.OrderInfoDTO;

/**
 * 訂單狀態管理器介面
 * @author
 *
 */
interface OrderStateManager {

	/**
	 * 建立訂單
	 * @param order 訂單
	 * @throws Exception
	 */
	void create(OrderInfoDTO order) throws Exception;
	
	/**
	 * 訂單能否執行取消操作
	 * @param order 訂單
	 * @return 能否執行取消操作
	 * @throws Exception
	 */
	Boolean canCancel(OrderInfoDTO order) throws Exception;
	
	/**
	 * 執行取消訂單操作
	 * @param order 訂單
	 * @throws Exception
	 */
	void cancel(OrderInfoDTO order) throws Exception;
	
	/**
	 * 判斷訂單能否進行支付操作
	 * @param order 訂單
	 * @return 能否進行支付操作
	 * @throws Exception
	 */
	Boolean canPay(OrderInfoDTO order) throws Exception;
	
	/**
	 * 執行支付訂單操作
	 * @param order 訂單
	 * @throws Exception
	 */
	void pay(OrderInfoDTO order) throws Exception;
	
	/**
	 * 完成商品發貨
	 * @param order 訂單
	 * @throws Exception
	 */
	void finishDelivery(OrderInfoDTO order) throws Exception;
	
	/**
	 * 判斷能否執行確認收貨的操作
	 * @param order 訂單
	 * @return 能否執行手動確認收貨的操作
	 * @throws Exception
	 */
	Boolean canConfirmReceipt(OrderInfoDTO order) throws Exception;
	
	/**
	 * 確認收貨
	 * @param order 訂單
	 * @throws Exception
	 */
	void confirmReceipt(OrderInfoDTO order) throws Exception;
	
	/**
	 * 判斷能否申請退貨
	 * @param order 訂單
	 * @return 能否申請退貨
	 * @throws Exception
	 */
	Boolean canApplyReturnGoods(OrderInfoDTO order) throws Exception;
	
	/**
	 * 申請退貨
	 * @param order 訂單
	 * @throws Exception
	 */
	void applyReturnGoods(OrderInfoDTO order) throws Exception;
	
	/**
	 * 拒絕退貨申請
	 * @param order 訂單
	 * @throws Exception
	 */
	void rejectReturnGoodsApply(OrderInfoDTO order) throws Exception;
	
	/**
	 * 退貨申請稽核通過
	 * @param order 訂單
	 * @throws Exception
	 */
	void passedReturnGoodsApply(OrderInfoDTO order) throws Exception;
	
	/**
	 * 寄送退貨商品
	 * @param order 訂單
	 * @throws Exception
	 */
	void sendOutReturnGoods(OrderInfoDTO order) throws Exception;
	
	/**
	 * 確認收到退貨商品
	 * @param order 訂單
	 * @throws Exception
	 */
	void confirmReceivedReturnGoods(OrderInfoDTO order) throws Exception;
	
	/**
	 * 完成退貨入庫
	 * @param order 訂單
	 * @throws Exception
	 */
	void finishedInputReturnGoods(OrderInfoDTO order) throws Exception;
	
	/**
	 * 完成退款
	 * @param order 訂單
	 * @throws Exception
	 */
	void finishedRefund(OrderInfoDTO order) throws Exception;
	
}

/**
 * 訂單狀態管理器
 * @author 
 *
 */
@Component
public class OrderStateManagerImpl implements OrderStateManager {

OrderStateManagerImpl 實現了訂單管理的操作邏輯

我們再新增一個增強類:LoggedOrderStateManager 來裝飾。

裝飾的增強類,實現了原類同樣的介面,並呼叫了同方法,再進行額外的日誌記錄操作


/**
 * 會自動記錄日誌的訂單狀態管理器
 * @author
 *
 */
@Component
public class  LoggedOrderStateManager implements OrderStateManager {

	/**
	 * 訂單狀態管理器
	 */
	@Autowired
	private OrderStateManagerImpl orderStateManager;
	/**
	 * 訂單操作日誌DAO元件
	 */
	@Autowired
	private OrderOperateLogDAO orderOperateLogDAO;
	/**
	 * 訂單操作內容工廠
	 */
	@Autowired
	private OrderOperateLogFactory orderOperateLogFactory;

	@Override
	public void create(OrderInfoDTO order) throws Exception {
		orderStateManager.create(order); 
		orderOperateLogDAO.save(orderOperateLogFactory.get(order, OrderOperateType.CREATE_ORDER));      
	}
	
	@Override
	public Boolean canCancel(OrderInfoDTO order) throws Exception {
		return orderStateManager.canCancel(order);
	}

	@Override
	public void cancel(OrderInfoDTO order) throws Exception {
		orderStateManager.cancel(order); 
		orderOperateLogDAO.save(orderOperateLogFactory.get(order, OrderOperateType.CANCEL_ORDER)); 
	}
	
	@Override
	public Boolean canPay(OrderInfoDTO order) throws Exception {
		return orderStateManager.canPay(order);
	}

	@Override
	public void pay(OrderInfoDTO order) throws Exception {
		orderStateManager.pay(order); 
		orderOperateLogDAO.save(orderOperateLogFactory.get(order, OrderOperateType.PAY_ORDER));  
	}

	@Override
	public void finishDelivery(OrderInfoDTO order) throws Exception {
		orderStateManager.finishDelivery(order); 
		orderOperateLogDAO.save(orderOperateLogFactory.get(order, OrderOperateType.GOODS_DELIVERY));  
	}

	@Override
	public Boolean canConfirmReceipt(OrderInfoDTO order) throws Exception {
		return orderStateManager.canConfirmReceipt(order);
	}

	@Override
	public void confirmReceipt(OrderInfoDTO order) throws Exception {
		orderStateManager.confirmReceipt(order); 
		orderOperateLogDAO.save(orderOperateLogFactory.get(order, OrderOperateType.CONFIRM_RECEIPT));  
	}

	@Override
	public Boolean canApplyReturnGoods(OrderInfoDTO order) throws Exception {
		return orderStateManager.canApplyReturnGoods(order);
	}

	@Override
	public void applyReturnGoods(OrderInfoDTO order) throws Exception {
		orderStateManager.applyReturnGoods(order); 
		orderOperateLogDAO.save(orderOperateLogFactory.get(order, OrderOperateType.APPLY_RETURN_GOODS));  
	}

	@Override
	public void rejectReturnGoodsApply(OrderInfoDTO order) throws Exception {
		orderStateManager.rejectReturnGoodsApply(order);
		orderOperateLogDAO.save(orderOperateLogFactory.get(order, OrderOperateType.RETURN_GOODS_REJECTED));  
	}

	@Override
	public void passedReturnGoodsApply(OrderInfoDTO order) throws Exception {
		orderStateManager.passedReturnGoodsApply(order);
		orderOperateLogDAO.save(orderOperateLogFactory.get(order, OrderOperateType.RETURN_GOODS_APPROVED));  
	}

	@Override
	public void sendOutReturnGoods(OrderInfoDTO order) throws Exception {
		orderStateManager.sendOutReturnGoods(order); 
		orderOperateLogDAO.save(orderOperateLogFactory.get(order, OrderOperateType.SEND_OUT_RETURN_GOODS));  
	}

	@Override
	public void confirmReceivedReturnGoods(OrderInfoDTO order) throws Exception {
		orderStateManager.confirmReceivedReturnGoods(order); 
		orderOperateLogDAO.save(orderOperateLogFactory.get(order, OrderOperateType.CONFIRM_RETURN_GOODS_RECEIPT));  
	}

	@Override
	public void finishedInputReturnGoods(OrderInfoDTO order) throws Exception {
		orderStateManager.finishedInputReturnGoods(order); 
		orderOperateLogDAO.save(orderOperateLogFactory.get(order, OrderOperateType.FINISHED_RETURN_GOODS_INPUT));  
	}

	@Override
	public void finishedRefund(OrderInfoDTO order) throws Exception {
		orderStateManager.finishedRefund(order); 
		orderOperateLogDAO.save(orderOperateLogFactory.get(order, OrderOperateType.FINISHED_RETURN_GOODS_REFUND));  
	}
	
}

相關文章