以前在个人博客(一枝花算不算浪漫)中已经更新过两篇设计模式相关的内容html
上面内容都是基于真实业务场景精简后的设计(工做中真实场景使用到的)。java
以前为了学习设计模式,看过网上不少相关博客讲解,大都是画下UML类图,举例几个绝不相干的demo,看了几遍仍然是云里雾里。数据库
由于本身如今作的项目就是属于B2C的商城,项目中使用到了大量的设计模式,因此这里精简真实的业务场景,将核心的业务代码抽离出来。代码不涉及任何公司信息,全部敏感信息都已屏蔽,代码只用做学习交流使用。设计模式
一图流,首先看下提交订单 咱们抽象出的一些场景:异步
订单中心: 一、订单中心建立订单 二、订单状态流转(状态模式) 三、记录操做日志(装饰器模式+简单工厂模式) 四、订单中心通知 库存中心更新库存ide
调度中心: 一、库存中心更新本地库存(使用命令模式+模板方法模式+工厂模式) 这个上讲已经说过:【一块儿学设计模式】命令模式+模板方法+工厂方法实战: 如何优雅的更新商品库存... 二、将更新库存数据放到消息中,调度中心消费消息(中介模式) 三、放入消息队列中,判断队列是否放满了,若是放满了须要创建离线存储(备忘录模式) 四、异步监听消息处理结果(观察者模式)学习
这个模型应该很简单,咱们来一步步拆解 一步步代码分析this
订单中心提交订单操做spa
/** * 订单状态管理器 */ @Autowired private LoggedOrderStateManager orderStateManager; public OrderInfoDTO save(OrderInfoDTO order) throws Exception { // 检查库存是否充足 if(!isStockEnough(order)) { return order; } // 将订单信息保存到本地数据库 saveOrder(order); // 订单状态流转 orderStateManager.create(order); // other logic return order; }
订单状态管理器设计
/** * 会自动记录日志的订单状态管理器 * @author wangmeng * */ @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)); } }
日志操做工厂
/** * 订单操做内容工厂 * @author wangmeng * */ @Component public class OrderOperateLogFactory { /** * 日期辅助组件 */ @Autowired private DateProvider dateProvider; /** * 获取订单操做内容 * @param operateType 订单操做类型 * @return 订单操做内容 */ public OrderOperateLogDO get(OrderInfoDTO order, Integer operateType) throws Exception { String operateContent = null; if(OrderOperateType.CREATE_ORDER.equals(operateType)) { operateContent = "完成订单建立,订单编号为:" + order.getOrderNo(); } else if(OrderOperateType.CANCEL_ORDER.equals(operateType)) { operateContent = "取消订单,订单编号为:" + order.getOrderNo(); } else if(OrderOperateType.PAY_ORDER.equals(operateType)) { operateContent = "支付订单,订单编号为:" + order.getOrderNo() + ",支付金额为:" + order.getPayableAmount(); } else if(OrderOperateType.GOODS_DELIVERY.equals(operateType)) { operateContent = "已经将订单中的商品进行发货"; } else if(OrderOperateType.CONFIRM_RECEIPT.equals(operateType)) { operateContent = "完成确认收货"; } else if(OrderOperateType.APPLY_RETURN_GOODS.equals(operateType)) { operateContent = "申请退货"; } else if(OrderOperateType.RETURN_GOODS_REJECTED.equals(operateType)) { operateContent = "退货申请审核不经过"; } else if(OrderOperateType.RETURN_GOODS_APPROVED.equals(operateType)) { operateContent = "退货申请审核已经过"; } else if(OrderOperateType.SEND_OUT_RETURN_GOODS.equals(operateType)) { operateContent = "寄送退货商品"; } else if(OrderOperateType.CONFIRM_RETURN_GOODS_RECEIPT.equals(operateType)) { operateContent = "确认收到退货商品"; } else if(OrderOperateType.FINISHED_RETURN_GOODS_INPUT.equals(operateType)) { operateContent = "完成退货商品入库"; } else if(OrderOperateType.FINISHED_RETURN_GOODS_REFUND.equals(operateType)) { operateContent = "完成退款"; } OrderOperateLogDO log = create(order, operateType, operateContent); return log; } /** * 建立订单操做日志 * @param operateType 订单操做类型 * @param operateContent 订单操做内容 * @return 订单操做日志 * @throws Exception */ private OrderOperateLogDO create(OrderInfoDTO order , Integer operateType, String operateContent) throws Exception { OrderOperateLogDO log = new OrderOperateLogDO(); log.setOrderInfoId(order.getId()); log.setOperateType(operateType); log.setOperateContent(operateContent); log.setGmtCreate(new Date()); log.setGmtModified(new Date()); return log; } }
订单状态流转 咱们只列出来订单create和cacel两种状态,由于状态流转时要判断当前状态是否能够流转到下一个状态,因此这里还有一个canCancel方法。
/** * 订单状态管理器接口 * @author wangmeng * */ 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; // 这里还会有更多的订单状态:支付、确认收货、发货、退货等等状态流转 }
OrderStateManager实现类
/** * 订单状态管理器 * @author wangmeng * */ @Component public class OrderStateManagerImpl implements OrderStateManager { /** * 已取消状态 */ @Autowired private CanceledOrderState canceledOrderState; /** * 待付款状态 */ @Autowired private WaitForPayOrderState waitForPayOrderState; /** * 建立订单 * @param order 订单 * @throws Exception */ @Override public void create(OrderInfoDTO order) throws Exception { waitForPayOrderState.doTransition(order); } /** * 订单可否执行取消操做 * @param order 订单 * @return 可否执行取消操做 * @throws Exception */ @Override public Boolean canCancel(OrderInfoDTO order) throws Exception { return getOrderState(order).canCancel(order); } /** * 执行取消订单操做 * @param order 订单 * @throws Exception */ @Override public void cancel(OrderInfoDTO order) throws Exception { canceledOrderState.doTransition(order); } /** * 获取订单状态组件 * @param order 订单 * @return 订单状态组件 * @throws Exception */ private OrderState getOrderState(OrderInfoDTO order) throws Exception { if(OrderStatus.WAIT_FOR_PAY.equals(order.getOrderStatus())) { return waitForPayOrderState; } else if(OrderStatus.CANCELED.equals(order.getOrderStatus())) { return canceledOrderState; } else if(OrderStatus.WAIT_FOR_DELIVERY.equals(order.getOrderStatus())) { return waitForDeliveryOrderState; } else if(OrderStatus.WAIT_FOR_RECEIVE.equals(order.getOrderStatus())) { return waitForReceiveOrderState; } else if(OrderStatus.FINISHED.equals(order.getOrderStatus())) { return finishedOrderState; } else if(OrderStatus.WAIT_FOR_RETURN_GOODS_APPROVE.equals(order.getOrderStatus())) { return waitForReturnGoodsApproveOrderState; } return defaultOrderState; } }
OrderState:
/** * 订单状态 * @author wangmeng * */ public interface OrderState { /** * 订单流转到当前这个状态 * @param order 订单 * @throws Exception */ void doTransition(OrderInfoDTO order) throws Exception; /** * 判断当前状态下可否执行取消订单操做 * @param order 订单 * @return 可否执行取消订单操做 * @throws Exception */ Boolean canCancel(OrderInfoDTO order) throws Exception; }
WaitForPayOrderState:
/** * 待付款状态 * @author wangmeng * */ @Component public class WaitForPayOrderState extends AbstractOrderState { @Autowired public WaitForPayOrderState(DateProvider dateProvider, OrderInfoDAO orderInfoDAO) { super(dateProvider, orderInfoDAO); } @Override protected Integer getOrderStatus(OrderInfoDTO order) throws Exception { return OrderStatus.WAIT_FOR_PAY; } @Override public Boolean canPay(OrderInfoDTO order) throws Exception { return true; } @Override public Boolean canCancel(OrderInfoDTO order) throws Exception { return true; } }
AbstractOrderState:
/** * 订单状态的抽象基类 * @author wangmeng * */ public abstract class AbstractOrderState implements OrderState { /** * 订单管理DAO组件 */ protected OrderInfoDAO orderInfoDAO; public AbstractOrderState(OrderInfoDAO orderInfoDAO) { this.orderInfoDAO = orderInfoDAO; } /** * 订单流转到当前这个状态 * @param order 订单 */ @Override public void doTransition(OrderInfoDTO order) throws Exception { Integer orderStatus = getOrderStatus(order); order.setOrderStatus(orderStatus); orderInfoDAO.updateStatus(order.getId(), orderStatus); } /** * 获取订单状态 * @param order 订单 * @return 订单状态 * @throws Exception */ protected abstract Integer getOrderStatus(OrderInfoDTO order) throws Exception; /** * 判断当前状态下可否执行取消订单操做 * @param order 订单 * @return 可否执行取消订单操做 */ @Override public Boolean canCancel(OrderInfoDTO order) throws Exception { return false; } }
上面只是讲了 订单中心提交订单中使用了状态模式
、简单工厂模式
、装饰器模式
状态模式:OrderStat + OrderStateManager等 简单工厂模式:OrderOperateLogFactory 装饰器模式:LoggedOrderStateMananger
其中LoggedOrderStateMananger实现了OrderStateManager接口,加强了create、cancel、pay等方法的实现,添加了记录日志的功能,使得状态流转后 能够自动记录日志的功能。
这里只是将精简后的代码提供出来,我相信认真看一下仍是很易懂的,后面还有提交订单 后面的一些流程,会单独在开一片文章来说解,敬请期待。
本文章首发自本人博客:https://www.cnblogs.com/wang-meng 和公众号:壹枝花算不算浪漫,如若转载请标明来源!
感兴趣的小伙伴可关注我的公众号:壹枝花算不算浪漫
原文出处:https://www.cnblogs.com/wang-meng/p/12038619.html