幸运星空

Lucker的程序人生

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

前言

可以说,订单管理模块是PetShop4中最值得去研究的模块了.因为它使用中多个重要的技术:工厂模式设计,策略模式设计,尤其是采用了订单的异步处理功能,Windows消息机制等高级技术.

订单的数据数设计

为了提高访问速度,PetShop4的订单数据是单独保存在一个数据库中的,这个数据库叫做:MSPetShop4Orders.在本系列博文第一篇中,我们就对该数据库做过比较详细的分析.这里不再多加描述.

订单的数据访问层

订单模块和购物篮模块一样,采用的是典型的工厂模式.

首先,分析订单的实体类,在PetShop4中,订单分为两部分,一部分是订单基本信息,保存在Order表中,另一部分是订单的详细商品信息,保存在LineItem表中,根据实体类和表的关系,因此实体类也分为两个:LineItemInfo类和OrderInfo类.它们的属性分别对应数据库中的两个表的字段.这些实体类都位于Model项目下.

接着,我们分析一下订单的数据访问类.数据访问类是DAL类的集中体现,系统中只用了一个类Order类,专门处理与订单有关的操作.以SQLServerDAL项目下的Order类为例,以下是Order类的结构如下图:

 image

 订单的业务逻辑层

业务逻辑层的提交订单分为两种方式:同步方式和异步方式.

同步是指用户提交订单后,把数据插入到表中后,再执行下面的操作;而异步是指用户提交订单后,数据的处理交给后台的MSMQ(消息队列)去处理,用户可以继续操作下面的内容,不需要等待本次订单完成.显然,异步处理可以大大提高操作的效率,不会影响用户折其他操作.

订单管理的BLL实现过程大致如下图所示:

image

与订单操作业务逻辑有于的类有三个:Order,OderAsynchronous和OrderSynchronous,均位于BLL项目下.

Order类,主要完成对订单的插入和获取订单信息的操作,具体结构如下图:

image

其中的几个静态变量的声明很修复注意:

// Using a static variable will cache the Order Insert strategy object for all instances of Order
// We implement it this way to improve performance, so that the code will only load the instance once
private static readonly PetShop.IBLLStrategy.IOrderStrategy orderInsertStrategy = LoadInsertStrategy();

//create a message query for an order.
private static readonly PetShop.IMessaging.IOrder orderQueue = PetShop.MessagingFactory.QueueAccess.CreateOrder();

// Get an instance of the Order DAL using the DALFactory
// Making this static will cache the DAL instance after the initial load
private static readonly IOrder dal = PetShop.DALFactory.DataAccess.CreateOrder();

而LoadInsertStrategy()方法将给我们返回一个策略算法实例.通过读取配置文件的方式,自动判断是采用同步处理还是异步处理.

OrderSynchronous类,采用同步处理的方法操作订单,此类和异步处理类OderAsynchronous一起继承自IOrderStrategy接口,IOrderStrategy接口位于IBLLStrategy项目下.OrderSynchronous类的代码如下:

public class OrderSynchronous : IOrderStrategy {

    // Get an instance of the Order DAL using the DALFactory
    // Making this static will cache the DAL instance after the initial load
    private static readonly PetShop.IDAL.IOrder dal = PetShop.DALFactory.DataAccess.CreateOrder();

    /// <summary>
    /// Inserts the order and updates the inventory stock within a transaction.
    /// </summary>
    /// <param name="order">All information about the order</param>
    public void Insert(PetShop.Model.OrderInfo order) {

        using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required)) {

            dal.Insert(order);

            // Update the inventory to reflect the current inventory after the order submission
            Inventory inventory = new Inventory();
            inventory.TakeStock(order.LineItems);

            // Calling Complete commits the transaction.
            // Excluding this call by the end of TransactionScope's scope will rollback the transaction
            ts.Complete();
        }
    }
}

代码中实现了父接口中定义的insert()方法,并通过一个事务更新商品的数量.

比较OderAsynchronous类的代码:

public class OrderAsynchronous : IOrderStrategy
{
    // Get an instance of the MessagingFactory
    // Making this static will cache the Messaging instance after the initial load
    private static readonly PetShop.IMessaging.IOrder asynchOrder = PetShop.MessagingFactory.QueueAccess.CreateOrder();

    /// <summary>
    /// This method serializes the order object and send it to the queue for asynchronous processing
    /// </summary>
    /// <param name="order">All information about the order</param>
    public void Insert(PetShop.Model.OrderInfo order) {

        asynchOrder.Send(order);
    }
}

insert()方法将要处理的订单操作完全交给了消息队列去处理了.asynchOrder在类中是一个MSMQ对象,通过些对象的"Send"方法实现消息的发送,消息保存在系统的MSMQ中.

MSMQ简介

MSMQ,微软消息队列,它使不在同一时间运行的程序,可以在不同各类的网络和可能暂时脱机的系统间进行通信.可用于同步和异步消息传递的解决方案.消息处理是异步处理的关键一点.MSMQ一个Windows组件,系统默认不安装,可通过"添加删除应用程序"实现安装.

消息处理类位于"System.Messaging"命名空间中.下面介绍几个重要的对象和方法:

1,初始化消息队伍代码:

MessageQueue Mq=new MessageQueue("hostname\\quequname");

消息队列中需要指明队列所以在机器和队列名.

2,也可以使用Path属性引用消息队列.

MessageQueue Mq=new MessageQueue();

Mq.Path="hostname\\quequname";

3,使用Create方法以编程方式创建队列:

MessageQueue Mq=new MessageQueue.Create("hostname\\quequname");

4,发送信息

Mq.Send(1000);

Mq.Send("Test");

5,接收消息,Recerve方法,接收消息的同时永久地从队列中删除消息,Peek方法接收后不从消息队列中移除消息.

Mq.Recerve();

Mq.Peek();

PetShop4中使用消息接口的设计,所有与消息相关的处理类都存放在IMessaging和MSMQMessaging项目下,在IMessaging项目中定义了IOrder接口,在MSMQMessaging中的Order类中实现了该接口,且Order类还继承了类PetShopQueue,以下是Order结构图:

image

Order类是实现消息队列的关键类,其中的Send方法和Receive方法并没有实现的完成队列操作,而是调用其父类PetShopQueue中的方法来完成.

实现订单的异步提交功能

前面研究了系统中要用到的实现异步提交的消息处理类,接下来将真正实现订单的异步提交功能

首先,创建MSMQ:在安装了MSMQ后,在计算机管理里可以找到“消息队列”结点,新建一个“专用队列”,命名要与配置文件中定义的一样,选中“事务性”。

接着,修改配置文件,实现异步功能。

image

下面,创建一个Windows服务实现后台订单处理,该服务程序根据指定的时间间隔,从队列中获取数据,执行订单的提交工作,这一切都在后台自动完成。注意,该服务采用了多线程操作。使用“InstallUtil”命令加载服务程序。并在Windows服务管理中设置该服务为自动运行。这样,当在PetShop4程序中异步提交订单时,订单数据就会出现在消息队列的专用队列中了。

订单模块的UI设计

订单的提交界面使用了Wizard控件,以向导的形式创建多个步骤。

 

 

 

 

 

 

 

 

 

 

posted on 2008-12-22 17:22  Lucker  阅读(635)  评论(0编辑  收藏  举报