《ASP NET程序设计案例教程》课件第9章_第1页
《ASP NET程序设计案例教程》课件第9章_第2页
《ASP NET程序设计案例教程》课件第9章_第3页
《ASP NET程序设计案例教程》课件第9章_第4页
《ASP NET程序设计案例教程》课件第9章_第5页
已阅读5页,还剩68页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第9章应用程序架构9.1应用程序架构9.2校园在线超市系统多层架构实现

【本章提要】

本章介绍了企业级应用多层设计的模式,阐述了应用分层的好处。并以校园在线超市用户注册模块为例,详细介绍了系统分层架构的实现过程。

【学习目标】

·理解从两层架构发展成多层架构。

·掌握将多层体系架构的理念融入到Web应用项目的设计和实施方法。

9.1.1将应用分层的好处

在大型公司里往往运行着大规模的软件系统,开发人员和分析师们专注于不同的应用层级。这确实是必须的,因为不可能让开发人员都理解某个层级所有的运行细节,若那样,则系统实在是太庞大了。

9.1应用程序架构想象一下某个保险公司里的应用程序必须完成的所有功能。从最简化的流程来说,保险公司要能接收新的保险单,评估与保险单相关的风险,向投保者开出账单,打印保险单然后将它邮寄出去,处理保险单的索赔,更新保险单,如果过期(或者没有支付费用)则取消保险单,等等。这一巨大的流程显然不仅仅是一个桌面应用程序所能处理的。

无论用户是不是想这么做,Web应用还是分层的好。如果用户是用SQLServer数据库存储数据的,那么数据库本身就已经是一个从Web服务器上分离出来的层了(即使物理上它们是在同一台计算机里)。作为一个面向对象的平台,ASP.NET使得这种分层操作更加容易了。应用程序分层使得整个开发更加容易,因为分层将某些特定目的操作封装成一个个独立的模块,它们可以单独维护和修改,同时也分散了维护的工作量。

例如,一个简单的在线零售程序采用了分层的思想,如图9-1所示。

从图中可以看出物理硬件分层与应用程序分层的结合。实际上有三个分层运行于一个Web服务器上,第一层是Web站点的用户界面层(UserInterface),它由业务规则层支持,业务规则层(BusinessRulesLayer)决定什么样的数据将被提供给用户界面层,业务规则层与数据访问层交互,而数据访问层则通过一个事务通道程序来获取所需要的数据,其他的客户服务和仓库系统也通过事务通道程序来获得所需的数据。

图9-1在线零售应用程序的分层每一层都仅仅关注于自身的功能实现,如业务规则层不需要知道任何关于数据存储方面的信息,它只需要了解由数据访问层提供的接口即可。事实上,业务规则层完全不必关心使用什么样的数据库,或者是否存在一个数据库。它只需要了解有一个数据访问层能用于交互,以及它可以通过一个公共的接口来交互数据即可。

尽管整个系统的完善需要集成测试,但是如果各层之间一致认同的接口没有发生改变,则我们可以在不干扰其他层的情况下改变任何一层的内部结构。9.1.2n级架构

任何关于应用程序架构的讨论中,如果没有提到经典的n级架构,那么就是不完整的。“n”代表任何数字,适用于描述我们所创建的应用程序。层(layer)或级(tier)的数目,由应用程序块的需求和结构来决定。

一般而言,甚至最基本的Web应用程序都能够被分离成三层:用户界面层(UI)、业务规则层(BusinessRulesLayer)以及数据层(DataLayer)。用户界面层就是用户能够见到的HTML和Web控件,业务规则层则承担着应用程序最重要的角色,而数据层则是数据库或者其他数据访问代码,这取决于应用程序的结构。如果需要,可以将应用程序分得更细:用户可以拥有用户界面(.aspx页面)、作为用户界面“粘合剂”而被页面继承的类或局部类、业务规则层(业务规则类)、数据访问层(数据访问类)以及数据层本身(数据库)。

假如由于某种原因,决定将SQLServer数据库替换为Oracle数据库,则如果没有将应用程序分层,而且把数据访问代码放在.aspx页面里,那么用户将不得不冒着把事情搞砸的风险,检查所有页面。这显然不是一种有效的代码管理方式。实际上,每个页面间操作数据的方式都不同。如果把所有的数据访问代码都放在单个层里,如一个拥有操作数据方法的类,这样就可以在不破坏业务规则或者用户界面的情况下对代码进行修改。

另一种很常见的情况是,假设在电子商务程序中,业务规则要求改变税款的计算方式,数据库没有变化,站点本身也不需要变化,仅仅是逻辑改变了,那就意味着只需要改变业务规则层中的类即可。再者,如果逻辑将创建在页面中或者是由某些数据库存储过程的计算所组成的,那么这项修改操作将变得十分困难。在一个极端的例子里,税率可能经常改变,那么就不能将税率硬编码到代码中。一般的解决方式是将税率存储在数据库中,并创建用户易于操作的相关工具。

9.2.1系统架构设计

微软

.NET平台可以方便快速地开发和部署多层架构应用程序。在校园在线超市系统中,其架构在逻辑上划分成数据实体层(DML)、数据访问层(DAL)、业务逻辑层(BLL)和应用层(UI)四层,如图9-2所示。9.2校园在线超市系统多层架构实现

图9-2系统分层架构设计从图中看出,这种分层结构易于理解,同时也使应用程序的维护和修改变得更加容易。假定我们要为MicrosoftAccess数据库创建一个新的数据访问层,则只需要改变数据访问层代码即可。通过用户界面进行的输入和输出数据的过程,实际上是在创建业务逻辑层的各种对象。例如,在应用程序中添加一个新的商品时,只需要创建一个商品对象,而不需要了解任何关于数据库中的具体细节。下面以“用户注册模块”为例,说明校园在线超市系统的多层实现过程。为了区分校园在线超市两层实现的定义,这里将解决方案命名为“NetShop”,在数据库设计和命名上也做一些改进。9.2.2数据实体层实现

数据实体层(DML,DataModelLayer)主要功能是实现关系数据库实体和实体关系表到应用程序对象的映射。数据库中有名为“Users”的实体表,用来存储注册用户的相关信息。打开VS2005,创建一个新网站,新建名为“Model”的文件夹,命名空间为“NetShop.Model”,在该文件夹下添加类库文件User.cs,创建用户类。相应代码编写如下:

usingSystem;

namespaceNetShop.Model

{

//<summary>

//实体类Users(属性说明自动提取数据库字段的描述信息)

//</summary>

[Serializable]

publicclassUsers

{

publicUsers()

{}

#regionModel

privateint_s_id; //用户ID

privatestring_s_name; //用户名称

privatestring_s_password; //用户密码

privatestring_s_qq; //用户QQ

privatestring_s_email; //Email

privatestring_s_phone; //联系电话

privatestring_s_address; //通信地址

privatestring_s_sex;//性别

privatestring_s_idcard; //身份证号

privateDateTime?_s_date; //出生日期

privatestring_s_answer; //密码答案

privatestring_s_question; //密码问题

privateint_s_type; //用户类型

privatestring_s_photo; //用户图片

privateint?_s_adminid;

//<summary>

//用户ID

//</summary>

publicints_id

{

set{_s_id=value;}

get{return_s_id;}

}

//<summary>

//用户名称

//</summary>

publicstrings_name

{

set{_s_name=value;}

get{return_s_name;}

}

//<summary>

//用户密码

//</summary>

publicstrings_password

{

set{_s_password=value;}

get{return_s_password;}

}

//<summary>

//用户QQ

//</summary>

publicstrings_qq

{

set{_s_qq=value;}

get{return_s_qq;}

}

//<summary>

//Email

//</summary>

publicstrings_email

{

set{_s_email=value;}

get{return_s_email;}

}

//<summary>

//联系电话

//</summary>

publicstrings_phone

{

set{_s_phone=value;}

get{return_s_phone;}

}

//<summary>

//通信地址

//</summary>

publicstrings_address

{

set{_s_address=value;}

get{return_s_address;}

}

//<summary>

//性别

//</summary>

publicstrings_sex

{

set{_s_sex=value;}

get{return_s_sex;}

}

//<summary>

//身份证号

//</summary>

publicstrings_idcard

{

set{_s_idcard=value;}

get{return_s_idcard;}

}

//<summary>

//出生日期

//</summary>

publicDateTimes_date//这里的?表示该属性可以为空

{

set{_s_date=value;}

get{return_s_date;}

}

//<summary>

//密码答案

//</summary>

publicstrings_answer

{

set{_s_answer=value;}

get{return_s_answer;}

}

//<summary>

//密码问题

//</summary>

publicstrings_question

{

set{_s_question=value;}

get{return_s_question;}

}

//<summary>

//用户类型

//</summary>

publicint?s_type

{

set{_s_type=value;}

get{return_s_type;}

}

//<summary>

//用户图片

//</summary>

publicstrings_photo

{

set{_s_photo=value;}

get{return_s_photo;}

}

//<summary>

//

//</summary>

publicint?s_adminid

{

set{_s_adminid=value;}

get{return_s_adminid;}

}

#endregionModel

}

}9.2.3数据访问层实现

当用户注册时,会向Users表插入一条记录。在本系统中,数据访问层(IDAL,DataAccessLayer)的实现分成以下三个步骤:

·定义对象接口类。

·实现数据访问接口类。

·定义数据工厂类创建对象接口。

1.定义对象接口类

在解决方案中创建文件夹“IDAL”,并定义此文件夹下命名空间为“NetShop.IDAL”、名为IUsers的接口。这样做是为了让数据访问层易于替换并支持其他数据库,使用接口来强制自己实现整个数据访问类的结构。代码如下:

usingSystem;

usingSystem.Data;

namespaceNetShop.IDAL

{

//<summary>

//接口层IUsers的摘要说明

//</summary>

publicinterfaceIUsers

{

#region成员方法

//<summary>

//得到最大ID

//</summary>

intGetMaxId();

//<summary>

//是否存在该记录

//</summary>

boolExists(ints_id);

//<summary>

//增加一条数据

//</summary>

intAdd(NetShop.Model.Usersmodel);

//<summary>

//更新一条数据

//</summary>

boolUpdate(NetShop.Model.Usersmodel);

//<summary>

//删除一条数据

//</summary>

boolDelete(ints_id);

//<summary>

//得到一个对象实体

//</summary>

NetShop.Model.UsersGetModel(ints_id);

//<summary>

//获得数据列表

//</summary>

DataSetGetList(stringstrWhere);

//<summary>

//获得前几行数据

//</summary>

DataSetGetList(intTop,stringstrWhere,stringfiledOrder);

//<summary>

//获得数据列表

//</summary>

intGetUser(stringstrWhere);

//<summary>

//修改基本信息

//</summary>

//<paramname="model"></param>

//<returns></returns>

boolUpdatajiben(NetShop.Model.Usersmodel);

//<summary>

//修改问题答案

//</summary>

//<paramname="model"></param>

//<returns></returns>

boolUpdataQuestion(NetShop.Model.Usersmodel);

//<summary>

//修改密码

//</summary>

//<paramname="model"></param>

//<returns></returns>

boolUpdatapassword(NetShop.Model.Usersmodel);

#endregion成员方法

}

}从上述代码上看,接口没有任何实现代码,它的根本目的在于让我们知道实现它的类应该具有的结构。这种方式对问题的理解更加直观,但是在业务逻辑层上要求能够访问接口实现类中的所有方法。要实现这个目的,可以根据web.config文件中的配置,结合反射来加载数据访问类并将其缓存。在数据工厂中,DataAccess类中CreateUsers的静态方法实现了这个功能。

2.实现数据访问接口类

在解决方案中,创建名为“SQLServerDAL”的文件夹,命名空间名为NetShop.SQLServerDAL,在此中建立名为“Users.cs”的类,实现IUsers接口。代码如下:

usingSystem;

usingSystem.Data;

usingSystem.Text;

usingSystem.Data.SqlClient;

usingNetShop.IDAL;

usingNetShop.DBUtility;//请先添加引用

namespaceNetShop.SQLServerDAL

{

//<summary>

//数据访问类Users

//</summary>

publicclassUsers:IUsers

{

publicUsers(){}

#region成员方法

//<summary>

//增加一条数据

//</summary>

publicintAdd(NetShop.Model.Usersmodel)

{

StringBuilderstrSql=newStringBuilder();

strSql.Append("insertintoNetShop_Users(");

strSql.Append("s_name,s_password,s_qq,s_email,s_phone,s_address,

s_sex,s_idcard,s_date,s_answer,s_question,s_type,s_photo,s_adminid)");

strSql.Append("values(");

strSql.Append("@s_name,@s_password,@s_qq,@s_email,@s_phone,

@s_address,@s_sex,@s_idcard,@s_date,@s_answer,@s_question,@s_type,

@s_photo,@s_adminid)");

strSql.Append(";select@@IDENTITY");

SqlParameter[]parameters={

newSqlParameter("@s_name",SqlDbType.VarChar,16),

newSqlParameter("@s_password",SqlDbType.VarChar,24),

newSqlParameter("@s_qq",SqlDbType.VarChar,12),

newSqlParameter("@s_email",SqlDbType.VarChar,30),

newSqlParameter("@s_phone",SqlDbType.VarChar,15),

newSqlParameter("@s_address",SqlDbType.VarChar,100),

newSqlParameter("@s_sex",SqlDbType.VarChar,2),

newSqlParameter("@s_idcard",SqlDbType.VarChar,20),

newSqlParameter("@s_date",SqlDbType.DateTime),

newSqlParameter("@s_answer",SqlDbType.VarChar,100),

newSqlParameter("@s_question",SqlDbType.VarChar,100),

newSqlParameter("@s_type",SqlDbType.Int,4),

newSqlParameter("@s_photo",SqlDbType.VarChar,100),

newSqlParameter("@s_adminid",SqlDbType.Int,4)};

parameters[0].Value=model.s_name;

parameters[1].Value=model.s_password;

parameters[2].Value=model.s_qq;

parameters[3].Value=model.s_email;

parameters[4].Value=model.s_phone;

parameters[5].Value=model.s_address;

parameters[6].Value=model.s_sex;

parameters[7].Value=model.s_idcard;

parameters[8].Value=model.s_date;

parameters[9].Value=model.s_answer;

parameters[10].Value=model.s_question;

parameters[11].Value=model.s_type;

parameters[12].Value=model.s_photo;

parameters[13].Value=model.s_adminid;

objectobj=DbHelperSQL.GetSingle(strSql.ToString(),parameters);

if(obj==null)

{

return1;

}

else

{

returnConvert.ToInt32(obj);

}

}

}

3.定义数据工厂类创建对象接口

在解决方案中,创建名为“DALFactory”的文件夹,命名空间名为NetShop.DALFactory,在此中建立名为“DataAccess.cs”的类来定义数据工厂,以实现数据访问。代码如下:

usingSystem;

usingSystem.Reflection;

usingSystem.Configuration;

namespaceNetShop.DALFactory

{

//<summary>

//AbstractFactorypatterntocreatetheDAL

//</summary>

publicsealedclassDataAccess

{

privatestaticreadonlystringAssemblyPath=ConfigurationManager.AppSettings["DAL"];

//<summary>

//创建Users数据层接口

//</summary>

publicstaticNetShop.IDAL.IUsersCreateUsers()

{

stringClassNamespace=AssemblyPath+".Users";

objectobjType=CreateObject(AssemblyPath,ClassNamespace);

return(NetShop.IDAL.IUsers)objType;

}

}

}9.2.4业务逻辑层实现

为了实现对用户注册信息的插入,业务逻辑层(BLL,BusinessLogicLayer)需要调用来自数据访问层的方法,并将相关值作为参数传递给它。BLL命名空间下的USers类中的Add方法实现了这一过程。代码如下所示:

usingNetShop.IDAL;

usingNetShop.DBUtility;

usingSystem.Text;

namespaceNetShop.BLL

{

//<summary>

//业务逻辑类Users的摘要说明

//</summary>

publicclassUsers

{

//定义访问用户对象的接口变量IUsers

privatereadonlyIUsersdal=DataAccess.CreateUsers();

publicUsers()

{}

#region成员方法

//<summary>

//增加一条数据

//</summary>

publicintAdd(NetShop.Model.Usersmodel)

{

returndal.Add(model);

}

}

}

这个方法完成了许多完全适合于业务逻辑层,并且不希望留给用户界面层或数据访问层的工作。9.2.5用户接口层实现

通过对业务逻辑进行封装后,用户接口层(UI,UserInterface)的设计就主要在页面设计和参数的传递了。用户接口层上可以在不知道应用程序其他部分细节的情况下调用业务逻辑层的方法来实现相应的业务逻辑,达到应用层和业务逻辑层的协同工作。其部分代码

如下:

publicpartialclassUiControl_user_add:System.Web.UI.UserControl

{

NetShop.BLL.Usersus=newNetShop.BLL.Users();

NetShop.Model.Usersuser=newNetShop.Model.Users();

stringimage="UpFiles/UserImages/none.gif";

protectedvoidBtnSubmit_Click(objectsender,EventArgse)

{

if(upImage())

{

user.s_name=tb_user_nam.Text.Trim();

user.s_password=Util.getpwd(tb_password.Text.Trim().ToString());

user.s_qq=tb_password.Text.Trim();

user.s_email=tb_email.Text.Trim();

user.s_phone=tb_phto.Text.Trim();

user.s_address=tb_adrees.Text.Trim();

user.s_sex=tb_sex.SelectedValue.ToString();

user.s_idcard=tb_user_id.Text.Trim();

user.s_date=DateTime.Now;

user.s_photo=image;

if(us.Add(user)>0)

JavaScript.alert("注册成功");

else

JavaScript.alert("注册失败");

}

else

{

JavaScript.alert("头像上传失败");

}

}

privateboolupImage()

{

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论