辣妹特工oox 迅雷下载:.Net Petshop详解[续] - torome - 博客园

来源:百度文库 编辑:九乡新闻网 时间:2024/04/26 06:09:26
.Net Petshop详解[续]
在这里,我将陆续的系列中逐步与大家一起探讨详解.Net Petshop的方方面面。
petshop概览和准备工作
前言
Microsoft公司为了配合推出.NET战略,不仅发布了一系列的开发工具和开发平台,同时还推出了.NET平台上的示范应用.其中的.Net Petshop就是极好的一例.这个电子商务的开发应用是为了应对J2EE平台而出炉的,在J2EE平台上Sun公司也有一个完整的实例----J2EE Petstore,它体现J2EE的BluePrint。二者解决的问题是一样的,功能也大同小异,界面也是如出一辙。自然是公说公有礼,婆说婆有礼了,我们姑且不管双方怎么声称自己的东西好,但是从中也能足见.NET和J2EE平台上的完美杰作是怎么样的一个实现。在这里,本人无意去争辩问题的胜负,也不打算去探讨J2EE是怎么样的解决方案和实现,只是作为纯粹的技术角度来管窥.NET平台上的.Net Petshop是如何一套的解决方案和实现的。我想,最好的学习,莫过于钻研这样的一套大的经典的系统,从设计的思想到最好的编码,毫无疑问对于我们将是大有裨益的。在这里,我将陆续的系列中逐步与大家一起探讨详解.Net Petshop的方方面面。希望大家多多指正!
.NET Pet Shop解决问题的描述
.NET Pet Shop是一个电子商务的实例,是在Microsoft的.NET平台上的一个具体实现。这个系统包含了B2C和B2B的实现。在这里我主要将的是B2C实现的部分,B2B在.NET Pet Shop里面不是重点要解决的问题。
.NET Pet Shop是一个在线的宠物购物系统,用户可以通过各种能够连接到internet的终端(包括移动终端)进行在线购物(具体界面见图一)。在这里,我将列出它将要实现的功能,也就是需求了:
(1)  用户帐号的管理功能:包括帐号创建,帐号登录,帐号维护;
(2)  产品浏览功能:类别浏览,具体产品浏览,详细信息,库存信息等等;
(3)  用户购物功能:添加购物,计算总价,下订单等等。

图一   .NET Pet Shop系统的登录主界面
.NET Pet Shop的逻辑结构
.NET Pet Shop按照三层的分层模型来部署整个系统。.NET Pet Shop分为数据展示层,中间层,数据层。这三层被清晰的分割为分布式应用的三个方面。其中数据展示层主要是完成界面和与最终用户交互的功能,在应用程序里面是一些aspx的页面和代码;中间层用于封装商业逻辑和规则,在应用程序里面被封装为.NET组件;数据访问通过中间层中的数据访问组件与SQL Server Provider交互,所有的数据获取依靠存储过程来进行,而不是通过SQL语句。图二是参考petshop的白皮书说明.NET Pet Shop的物理部署结构。

图二  .NET Pet Shop部署结构
.NET Pet Shop的开发环境支持
Microsoft的.NET战略是如此的宏大,同样的.NET Pet Shop需要的开发环境同样是很壮观的。以下是我调试.NET Pet Shop的环境,有些东西是可以替换的,有些不是必须的。大家可以根据自己的情况调整。
(1) 操作系统win2000 server,web服务器IIS5.0,数据库服务器SQL Server 2000;
(2) 开发工具Visual Studio.NET企业设计版。
在这里如果大家想很快的知道.NET Pet Shop 的UML模型,可以利用Visio来进行反向工程,就可以自动生成静态的类图(但是不可能生成用例图和序列图等等的)。同时Visio也可以对已经有的petshop数据库进行反向工程,生成数据库模型,从而对理解.NET Pet Shop大有帮助,也能够管窥一点微软的建模方法和设计过程。
.NET Pet Shop系统的安装
.NET Pet Shop的示例程序代码和白皮书可以在Microsoft的msdn网站上下载到,也可以到http://www.gotdotnet.com/compare去下载。
在petshop的文件夹下有database、petshopdoc和web以及webservice几个文件夹。Database是数据库的安装脚本,将你的数据库的sa密码设置为空即可直接运行这些脚本安装。Petshopdoc是英文的白皮书,后面的比较有参考价值了。Web是我们将要讨论的大部分程序代码。Webservice是用于发布的web服务。
petshop三层结构之DataTier
交互的三层综述
在前面的文章中,我们丛整个系统的角度了解了petshop的三层部署结构物理上的一个概貌,没有从应用程序的角度来说明是如何划分的,也不清楚数据展示层,中间层,数据层是如何交互的。为了更好的说明这个三层的结构以及每一层的具体细节问题,也让大家对整个应用有一个walkthrough,在这里我将说明从系统的角度来看(见参考图1),顾客在购物的过程中,系统的三层是如何的工作以及如何的交互。这个东西有点象UML里面的实例情景故事,对需求和分析的进一步是大有帮助的。

图1 .NET Petshop 架构
从这个情景中,我们可以很清晰的了解到Internet Customer在购物时系统的运作情形。首先通过数据展示层的用户交互界面Cart.aspx页面输入顾客购买的商品以及数量,然后这些购物清单由后台的应用程序(cart.aspx.cs)做相应的预处理(如安全验证,校验,数据的格式化等等),接着调用中间件(在程序结构里面就是一些.NET Assembly,封装了购物的商业逻辑),最后通过数据访问接口来更新数据库里面的数据(数据层)。
数据层(Database)
.NET Petshop的数据库并不是十分的庞大,总共有12个用户表和23个存储过程。Petshop数据库里面存储的是用户数据,帐号数据,产品数据,用户配置数据,订单数据,库存数据以及供应商的数据。应用程序访问数据库的数据并不是直接的与数据库表打交道,而是通过存储过程的运行来获取所需要的数据。这样的设计有一个好处就是,避免了频繁的表操作,而通过运行在服务器端的存储过程可以极大的提高运作效率和提升访问数据的速度,同时也很好的屏蔽了数据库表的逻辑,使得数据库访问变成了数据库提供的服务访问。当然,也有人指责说这些存储过程迁移性是值得怀疑的。
下面我将通过表格把这些数据库的基本表列出来(见表1),并一一做说明,希望对大家深入的理解有帮助。
表名称
备注信息
Account
基本用户信息。
BannerData
存储的是系统界面的banner图片的设置信息。
Category
宠物的类别目录表(比如鱼类,狗类等等)。
Inventory
宠物产品的存货信息。
Item
单个产品的详细信息。
LineItem
订单的每一项的详细信息,包括产品名称和数量,价格等。
Orders
用户购物的订单,一个订单可以包括多项LineItem
OrderStatus
订单的状态
Product
宠物的产品列表,一条Product可能包括多个Item
Profile
用户配置表,用于记录他们的favorites。
Signon
用户帐号登陆表,因为常用,故从Account独立出来。
Supplier
供应商信息。
通过上表我们知道了petshop数据库的数据库表的一些信息,但是这些表之间到底是一种什么样的关系呢?关心数据库建模和设计的人可能对这个问题比较感兴趣。在这里,我将给出图表(图2)说明这些数据库表之间的关系。图2中列出了这些表之间的关系和主键信息。

图2:petshop数据库物理设计模式
技巧:其实对于从事过数据库建模和设计的人都知道,得到上面的数据库模型图形并不是一件很困难的事情。正如我们前面提到的一样,我们可以用Visio做工程反转就可以得到上面这么美观的设计模型图了。同时,我们也可以在模型图中做修改设计,可以马上应用到你的物理数据库,使其保持同步。
说完了基本的数据库表,接下来我们看看存储过程。用微软的话说,只有设计称存储过程,才算是”cleaner separation of code from the middle-tier”,我个人觉得这样做是很好的。同样的,我把它列在一个表格里(表2)。
存储过程名称
备注信息
upAccountAdd
增加一个帐号。
upAccountGetAddress
获取用户的地址,主要用于下订单时注册地址与送货地址不一。
upAccountGetDetails
获取帐号的详细信息。
upAccountLogin
用户登陆验证。
upAccountUpdate
更新用户帐号。
upCategoryGetList
获取某个类别的产品列表。
upInventoryAdd
增加指定的项到存活信息。
upInventoryGetList
获取存货列表。
upItemAdd
增加一项产品。
upItemGetDetails
获取指定产品项的详细信息。
upItemGetList
获取某一特定类别的产品的具体项目列表。
upItemGetList_ListByPage
功能与上同,但是分页获取数据。
upOrdersAdd
增加一项订单。
upOrdersGet
获取某一订单的信息。
upOrdersGetDetails
获取某一订单的详细信息。
upOrderStatusGet
获取订单的状态。
upProductAdd
增加一类别产品。
upProductGetList
返回某类产品的列表。
upProductGetList_ListByPage
与上同,但是分页获取结果数据。。
upProductSearch
产品搜索。
upProductSearch_ListByPage
与上同,但是翻页获取结果数据。
upProfileGetBannerOption
Banner的配置信息。
upProfileGetListOption
获取用户配置信息。
表2:petshop存储过程列表
在这些存储过程里面使用了SQL Server2000的OpenXML的特性来代替传统的行集结果,使用在非常频繁的数据访问操作,可以减轻系统的负担。
好了,petshop的Datatier就说到这里了,在后面的文章我会就一个数据访问的实例再次解说存储过程的执行。接下来我将就中间层做介绍了。
petshop三层结构之MiddleTire
通过前面的文章,我们对.NET Petshop的整个结构有了一个大致的了解,也清楚的知道了数据库的设计模式和实现的细节,尤其值得一提的是通过存储过程访问数据库。在接下来的这篇文章里,我将和大家一起来探究一下.NET Petshop的中间层。
根据三层结构的设计原则,中间层封装的是业务逻辑和规则,在这个网络宠物商店的例子中,购物处理,订单处理,帐号管理,产品查询等等都是具体的业务逻辑,至于与用户交互并不是中间层要处理的问题。它处理是与具体的用户界面和交互无关,而仅仅是核心的商业规则和逻辑。.NET Petshop的中间层业务逻辑被封装为一个.NET 组件,它的命名空间为Pet Shop.Components(编译后在bin的文件夹里面有一个petshop.dll的文件)。图1是.NET Petshop解决方案中间层的类视图和文件视图。


图1:.NET Petshop解决方案中间层的类视图和文件视图
接下来,我们模拟顾客到百货超市采购日常用品的过程来说明运作的流程以及抽象出重要的概念(实际上User case,我们在领域分析的时候会这么做,并且是很重要的一步,从这里可以初步的发现在我们实施的系统中将要涉及到的逻辑实体,进而可以为数据库建模设计以及类设计提供参考)。
购物用例的业务分析:
1 客户有购买商品的意愿;
2 客户到登陆管理员处登记,且成功登记;
3 在登记处推一个购物车;
4 在超市内查找所购商品类别存放的货架;
5 在具体的货架上查找某一具体品牌的商品;
6 将符合意愿的商品放入自己的购物车;
7 重复4-6;
8 购物完毕;
9 到付款处计算总价格并付款;
10 打印购物清单;
11 退还购物车;
12 取走购物,购物完毕;
备注:在这个用例中,我们做了一些前提和假设,为的是方便.NET Petshop的分析,比如说在实际生活中根本就不需要第二步。
通过这个用例的分析,我们至少可以抽象出一下几个重要概念,并且能在应用程序里面找到对应的类:客户对应Customer、商品对应Product、购物车对应ShoppingCart、商品类别对应Category、具体商品对应Item、清单对应Order。
正如我前面说过的,这几个概念对于我们的业务建模和系统建模是非常有用的。正是通过这样的分析,在.NET Petshop的业务逻辑里面共有9个核心类和5个轻量级的数据结构类。同样的方式,我在这里列出这些类,并加以说明(见表1)。
类名称
说明
BasketItem
代表购物车ShoppingCart里的一项购物商品。
Customer
用于帐号管理和登陆验证。
CustomerDetails
用户帐号的详细信息。
CustomerAddress
用户帐号的地址信息。
Error
用于登陆出错的帮助功能。
Item
代表某类产品中的具体一项商品。
ItemResults
搜索Item的结果集。
Order
购物完毕后的购物清单和订单。
Product
大类别里面的某类产品。
ProductResults
搜索产品的结果集。
Profile
用户的配置。
ShoppingCart
购物车,用于购物的整个过程,直到下订单。
Database
通过ADO.NET访问数据库,封装了具体的访问方法。
SearchResults
模糊搜索的结果集。
表1:.NET Petshop中间层的类
CustomerAddress, CustomerDetails, ItemResults, ProductResults, and SearchResults这几个轻量级的数据结构类为在数据层和展示层之间提供了一种松散的数据绑定调用。这些类都被设计为有公开的属性,ASP.NET 的web页面可以通过这些属性访问数据。下面这段类的代码说明了这5个类是如何暴露自己的公开属性供展示层使用的。
public class ProductResults
{
private string m_productid;
private string m_name;
public string productid {
get { return m_productid; }
set { m_productid = value; }
}
public string name {
get { return m_name; }
set { m_name = value; }
}
}
在.NET Petshop详解(二)中我们就说过数据库的访问是通过存储来进行的,我们看看下面这部分代码就知道了:
public string Login(string userName, string password) {
string customerID;
// params to stored proc
Database data = new Database();
SqlParameter[] prams = {
data.MakeInParam("@username",    SqlDbType.VarChar, 25, password),
data.MakeInParam("@password",    SqlDbType.VarChar, 25, userName),
data.MakeOutParam("@CustomerID", SqlDbType.VarChar, 25)
};
// create data object and params
data.RunProc("upAccountLogin", prams);    // run the stored procedure
customerID = (string) prams[2].Value;     // get the output param value
// if the customer id is an empty string, then the login failed
if (customerID == string.Empty)
return null;
else
return customerID;
}
这段代码是Customer类的Login方法,它是通过将用户输入的用户名userName和密码password做为输入参数传递给存储过程upAccountLogin的,这个存储过程完成在Sigon用户帐号表里面查找该用户是否合法,最后返回一个字符串的用户ID值。在这里没有使用SQL查询语句,很好的分离了逻辑。具体的数据库访问是通过Database来完成的,我们将在后面的文章中继续探讨它的运作。
ShoppingCart是比较有意思的一个类,也是很重要的一个类。它是与状态有关的一个类,在.NET Petshop里面,它的状态是通过ASP.NET Session state来管理的,关于其进一步的细节留待后面讨论。
.NET Petshop的中间层的探讨先到此,我在这里只是抛砖引玉,很多的东西要深入代码才可以搞的更加清楚。欢迎大家继续与我一起关注下一篇.NET Petshop的数据展示层。
petshop三层结构之PresentationTier
在前面的文章中,我们已经就.NET Petshop的数据层和中间的业务逻辑层作了说明,接下来的文章中,我们将就数据展示层作探究。与前面的两层有着很大的差别的是,.NET Petshop的展示层用了很多Microsoft最新的web Forms技术即Asp.NET。因此,在解说展示层之前,我想就Asp.NET在.NET Petshop的开发中使用到的非常重要的特性做一些说明,以示区别:
(1)       Asp.NET代码不再是解释型代码,可以经由JIT编译器编译后运行,并且引入了很好的页面缓冲机制。
(2)       ASP.Net的配置模型引入了基于XML文件的“零安装”配置模型。零安装的含义是只需将配置文件Web.config,应用程序拷贝到系统指定的目录下即可,需要更改时直接在文件里更改并保存。
(3)       安全管理 ASP.Net提供了比传统ASP更强大可靠的安全管理。Asp.NET提供了三种验证方式以及两种类型的授权服务。
(4)       支持代码和页面内容的分离。回想以前编写Asp程序的时候的问题:代码逻辑混乱,难于管理。
(5)       提供了更好的状态管理,包括会话状态的管理和视图状态的管理。
(6)       大量的ASP.NET服务器端控件和对用户控件的开发的支持。
.NET Petshop充分的使用了服务器控件技术和会话状态管理。展示层的交互界面均采用aspx页面,后端有分离的逻辑代码。.NET Petshop共有19个aspx页面和代码逻辑。在这里一一里列出,并说明设置参数和其作用。
ASP.NET Web页面
EnableSessionState
EnableViewState
备注说明
Cart.aspx
true
true
购物清单
Category.aspx
True
false
产品分类的列表
CheckOut.aspx
Readonly
false
订单确认
CreateNewAccount.aspx
False
true
创建新帐号
Default.aspx
False
false
系统首页面
EditAccount.aspx
False
true
账号编辑
Error.aspx
False
false
错误处理
Help.aspx
False
false
帮助
OrderAddressConfirm.aspx
readonly
false
订单地址确认
OrderBilling.aspx
True
true
订单信息
OrderProcess.aspx
readonly
false
下订单
OrderShipping.aspx
True
true
订单地址和姓名
Product.aspx
False
false
产品列表
ProductDetails.aspx
false
false
产品详细信息
Search.aspx
false
false
搜索
SignIn.aspx
false
false
帐号登陆
SignOut.aspx
true
false
帐号退出
ValidateAccount.aspx
false
false
帐号创建确认
VerifySignIn.aspx
false
false
账号登陆确认
.NET Petshop使用了很多用户控件,这些控件位于web/Inc目录下面。表格2对用户控件作出说明:
User Controls
EnableViewState
备注说明
ControlAddress
true
详细地址列表
ControlBanner
false
页面底部的banner
ControlCart
true
购物清单
ControlFavList
false
个人Favorites列表
ControlHeader
false
页面顶部的菜单和链接
ControlStaticAddress
false
不能编辑的地址信息
下面列出一段代码,说明这些参数的设置和用户控件的引用:
/*  摘自Cart.aspx   */
<%@ Register TagPrefix="PetShop" TagName="Cart" Src="Inc/ControlCart.ascx" %>
<%@ Register TagPrefix="PetShop" TagName="Header" Src="Inc/ControlHeader.ascx" %>
<%@ Page language="c#" Codebehind="CheckOut.aspx.cs" AutoEventWireup="false" Inherits="PetShop.Web.CheckOut" EnableSessionState="readonly" enableViewState="False"%>
开始的两个Registe指令用于引用ControlCart和ControlHeader的用户控件,Page指令定义 ASP.NET 页分析器和编译器使用的页特定的属性。
在控件的排放位置使用下面的代码既可以显示该控件了:

在上面的代码中allowedit一项是向实例化的ctlCart传递参数。我个人认为用户控件是一个很好的东西,可以简化web页面的开发模型又可以达到代码复用的目的,而且其开发非常简单,与aspx的开发基本是一样的。图1说明了设计模式下和运行时的用户控件。

接下来的文章我们将就系统配置和安全管理作进一步的说明。
分类:PETSHOP3.0宠物商店