装饰器模式:
对目标类的功能进行增强,但是又不想去直接修改原来的类的代码,因为一旦修改就得重新测试这个类,违背“对扩展开放,对修改关闭”的原则。
另外,有的时候想增强的类是别人给的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));  
	}
	
}