热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

用MediatorPattern+Queue解决订单处理流程

对旅游电子商务来说,订单处理系统是个复杂的系统,它围绕产品,供应商,支付,配送等要素形成一套复杂的流程。它涉及

  对旅游电子商务来说,订单处理系统是个复杂的系统,它围绕 产品,供应商,支付,配送等要素形成一套复杂的流程。

  它涉及到不同类型的产品,如机票,酒店,门票。以价格为例 机票价格直接通过中航信系统进行确认;对于香港酒店需要实时确认价格,国内酒店则是每天确认一次;如果门票,从代理商拿的价格和从景点拿到价格是不一样的。

  更不用说支付和配送。机票可以采用信用卡支付和Post机;酒店一般是面付+预付;门票可能是拿着换购券到景区买票。

  面对这些复杂的问题,有没有可以行的办法。让我们分析一下。订单处理系统围绕下几个要素进行的:流程、操作、状态。

  订单的处理流程 主要由 订单和产品决定的,同时订单流程走到哪,操作就走到哪。通常来说,我们通常此采用简单的状态机来应对,在那些状态下允许那些操作,不允许那些操作。随着业务发展会遇到各种问题:如上下游节点耦合,流程变化引起的更变点多。

  如何解决这个问题。我的方案就是使用 Mediator Pattern + Queue.

  OperationQueue是 订单操作队列,存放 需要进行某种操作的订单。比如比如payQueue 说明 订单可以进行支付;deliverQueue说明可以进行配送。它的实现方式有很多种,根据不要的需要可以存在JVM,DB,Cached。

  OperationQueue的核心方法为:

    getName():返回队列名称。

    addOrderToQueue:把订单添加到队列中。

    removeOrder:订单要在各种操作队列中转移,需要删除队列中的旧订单。

    findOrder:获取指定订单。

  OrderFlowMediator 根据各种状态,决定order应该到哪种操作队列中。  

    核心方法:dispathOrder(Order),转发订单到不同的操作队列中,他必须在业务操作完成之后才能调用,简单的说法,就是业务数据持久化后,才能调用。

 

  相关代码如下:

package com.ming.article.pattern.order.mediator;

import com.ming.article.pattern.order.Order;

public interface OperationQueue {

public String getName();

public void addOrderToQueue(Order order);

public void removeOrder(Order order);

public Order findOrder(Order order);

}

 

package com.ming.article.pattern.order.mediator;

import java.util.LinkedList;

import com.ming.article.pattern.order.Order;


public class MemoryOperationQueue implements OperationQueue {

private String name ;
private LinkedList list = new LinkedList();

public MemoryOperationQueue(String name){
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public void addOrderToQueue(Order order) {
list.addLast(order);
}

@Override
public void removeOrder(Order order) {
list.remove(order);

}
@Override
public Order findOrder(Order order) {
for(Order o:list){
if(o.equals(order)) return o;
}
return null;
}

}

 

package com.ming.article.pattern.order.mediator;
/**
* 订单操作队列
*
@author martin.chen
*
*/
public class OrderOperationQueue {
/**
* 与客户确认订单队列
* 客户下完订单后,需要确认 出行人的各种信息
*/
private OperationQueue confrimCustomer =new MemoryOperationQueue("confrimCustomer");

/**
* 与供应商资源队列
* 客户预订的订单后,还需要跟供应商确认产品是否可以提供
*/
private OperationQueue confirmResoruce =new MemoryOperationQueue("confrimResource");

/**
* 进行支付队列
* 确认客户和供应商之后,才可以进行付款
*/
private OperationQueue payQueue =new MemoryOperationQueue("pay");

/**
* 配送产品队列
* 付款成功后,就可以进行配送
*/
private OperationQueue deliverQueue = new MemoryOperationQueue("delivery");

public OperationQueue getConfrimCustomer() {
return confrimCustomer;
}

public OperationQueue getConfirmResoruce() {
return confirmResoruce;
}

public OperationQueue getPayQueue() {
return payQueue;
}

public OperationQueue getDeliverQueue() {
return deliverQueue;
}

}

 

package com.ming.article.pattern.order.mediator;


import com.ming.article.pattern.order.Order;
import com.ming.article.pattern.order.OrderStatus;

public class OrderFlowMediator {


OrderOperationQueue operatioinQueue = new OrderOperationQueue();

/**
* 转发订单到不同的队列
*
@param order
*/
public void dispathOrder(Order order){


//清楚
if(order.getOrderStatus().equals(OrderStatus.Commited) && !order.isConfirmCustomer()){

operatioinQueue.getConfrimCustomer().addOrderToQueue(order);
return;
}

if(order.getOrderStatus().equals(OrderStatus.Commited) && !order.isConfirmResource()){
operatioinQueue.getConfirmResoruce().addOrderToQueue(order);
operatioinQueue.getConfrimCustomer().removeOrder(order);
return;
}

if(order.getOrderStatus().equals(OrderStatus.Commited)
&& order.isConfirmCustomer() && order.isConfirmResource()
&& !order.isPaid()){
operatioinQueue.getPayQueue().addOrderToQueue(order);
operatioinQueue.getConfirmResoruce().removeOrder(order);

return;
}
if(order.getOrderStatus().equals(OrderStatus.Commited)
&& !order.isDelivered()){
operatioinQueue.getDeliverQueue().addOrderToQueue(order);
operatioinQueue.getPayQueue().removeOrder(order);

return;
}

}

public OrderOperationQueue getQueue(){
return operatioinQueue;
}

}

 

package com.ming.article.pattern.order;

import com.ming.article.pattern.order.mediator.OrderFlowMediator;


public class OrderDCI {

private OrderFlowMediator mediator;

public OrderDCI(OrderFlowMediator mediator){
this.mediator = mediator;
}
public void confirmCustomer(Order order,Object params) {
order.setConfirmCustomer(true);
System.out.println("确认客户成功");
mediator.dispathOrder(order);
}

public void confirmResource(Order order,Object params) {

order.setConfirmResource(true);
System.out.println("确认资源成功");
mediator.dispathOrder(order);
}

public void payOrder(Order order,Object params) {
order.setPaid(true);
System.out.println("支付成功");
mediator.dispathOrder(order);

}

public void deliveryOrder(Order order,Object params) {
order.setDelivered(true);
System.out.println("配送成功");
mediator.dispathOrder(order);

}
}

 

package com.ming.article.pattern.order;
public class Order {

private OrderStatus orderStatus = OrderStatus.Draft;
private boolean confirmResource = false;
private boolean confirmCustomer = false;
private boolean paid = false;
private boolean delivered = false;
public OrderStatus getOrderStatus() {
return orderStatus;
}
public void setOrderStatus(OrderStatus orderStatus) {
this.orderStatus = orderStatus;
}
public boolean isConfirmResource() {
return confirmResource;
}
public void setConfirmResource(boolean confirmResource) {
this.confirmResource = confirmResource;
}
public boolean isConfirmCustomer() {
return confirmCustomer;
}
public void setConfirmCustomer(boolean confirmCustomer) {
this.confirmCustomer = confirmCustomer;
}
public boolean isPaid() {
return paid;
}
public void setPaid(boolean paid) {
this.paid = paid;
}
public boolean isDelivered() {
return delivered;
}
public void setDelivered(boolean delivered) {
this.delivered = delivered;
}

}

 

package com.ming.article.pattern.order;
public enum OrderStatus {

Draft,//草稿
Commited,//提交
Finish;//完成
}


  测试代码如下:

package com.ming.article.pattern.order;

import org.junit.Test;

import com.ming.article.pattern.order.mediator.OrderFlowMediator;

public class OrderMediatorTest {

private OrderFlowMediator mediator = new OrderFlowMediator();
private OrderDCI dci = new OrderDCI(mediator);

@Test
public void test() {
// 提交订单
Order order = new Order();
order.setOrderStatus(OrderStatus.Commited);
mediator.dispathOrder(order);

// 确认客户
Order order1 = mediator.getQueue().getConfrimCustomer()
.findOrder(order);
dci.confirmCustomer(order1, "Tom");

Order order2 = mediator.getQueue().getConfirmResoruce()
.findOrder(order);
dci.confirmResource(order2, null);

// 支付
Order order3 = mediator.getQueue().getPayQueue().findOrder(order);
dci.payOrder(order3, null);

// 支付
Order order4 = mediator.getQueue().getDeliverQueue().findOrder(order);
dci.deliveryOrder(order4, null);

}
}








转载于:https://www.cnblogs.com/MartinChen999/archive/2011/12/26/2301805.html


推荐阅读
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • LeetCode笔记:剑指Offer 41. 数据流中的中位数(Java、堆、优先队列、知识点)
    本文介绍了LeetCode剑指Offer 41题的解题思路和代码实现,主要涉及了Java中的优先队列和堆排序的知识点。优先队列是Queue接口的实现,可以对其中的元素进行排序,采用小顶堆的方式进行排序。本文还介绍了Java中queue的offer、poll、add、remove、element、peek等方法的区别和用法。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 本文介绍了使用Spark实现低配版高斯朴素贝叶斯模型的原因和原理。随着数据量的增大,单机上运行高斯朴素贝叶斯模型会变得很慢,因此考虑使用Spark来加速运行。然而,Spark的MLlib并没有实现高斯朴素贝叶斯模型,因此需要自己动手实现。文章还介绍了朴素贝叶斯的原理和公式,并对具有多个特征和类别的模型进行了讨论。最后,作者总结了实现低配版高斯朴素贝叶斯模型的步骤。 ... [详细]
  • Todayatworksomeonetriedtoconvincemethat:今天在工作中有人试图说服我:{$obj->getTableInfo()}isfine ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
author-avatar
两斤
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有