Draft-2003-03-26
本文的读者对象为熟悉ASP.NET的中、高级开发人员与系统构架工程师
本文详细讨论了基于ASP.NET的系统的设计模式和软件体系构架。
完美Web Tier Application的设计目标... 2
基于Microsoft平台的软件工程师和软件厂商已渐渐将开发的平台转移到.NET上,特别是在Web的编程方面,ASP.NET已被广泛的采用。
ASP.NET的出现给其相应的设计模式带来一个真空地带。人们在学习ASP.NET的同时,却有可能忽略对其相应的设计模式的研究与学习,正如最初使用J2EE时,工程师们在新的编程模型下感到不知所措。在本文主要探讨ASP.NET的应用带来的设计模式上的转变。
由于本文的目的不是教会读者如何使用ASP.NET,所以下面仅对ASP.NET中基于事件驱动的编程模型加以介绍。
ASP.NET 的核心WebForm采用了事件驱动的编程模式,这对于习惯与采用ASP编写Web程序的软件工程师来说,将是一种根本的编程思路的改变,如果不能改变,你将很难掌握ASP.NET的精髓。
事实上WebForm的事件驱动模型与Windows窗口的基于消息的编程模式非常类似。这也看出WebForm的设计者的设计意图。下表对Page中的事件和Dialog事件进行了对比:
Page事件 |
Dialog事件 |
Page_Init |
INIT_DIALOG |
Page_Load |
WM_SHOW |
Render |
WM_PAINT |
同时Page中的WebControl,与Dialog中的各种控件也十分类似,都可以设置特定的消息处理函数。
所以,如果在设计、编写WebForm时,更多的将WebForm想象成Dialog则会大有益处。
由此可见ASP.NET的事件驱动模型,给Web Tier Application的设计模式带来了重大的转变,你不可能在沿用ASP的设计思路和方法。
长期以来,Web Tier Application的混乱与复杂,使得人们耿耿于怀,甚至使得软件高手们编写Web Tier Application的兴趣与日俱减。无论你采用何种技术ASP, JSP, CGI, PHP,HTML,都不可能使得程序结构清晰易于维护。
一个完美的Web Tier Application的体系构架应具有以下特点:
1、 用户界面与应用逻辑的分离,有效的隔离开发人员的角色。用户界面与应用逻辑的紧密耦合是Web应用程序的天生缺陷,在编写CGI时甚至要使用printf将整个页面输出。为了追求Web 页面的完美通常界面的设计与应用逻辑的实现是两种类型的工程师。一个擅长使用Photoshop与Dreamwave毕业于艺术院校,一个只懂得C++与Java整天敲击键盘,要让这两种人才合并简直是Mission Impossible。在这种背景下,用户界面与应用逻辑紧密耦合的矛盾与日俱增,同时能使这两种开发人员的工作有效分离的设计模式将会大大提高生产效率。
2、 提供中心控制机制。Web页面之间相互连接,这在给用户提供方面的同时使得整个系统难以维护,系统逻辑混乱。好的设计模式应提供中心控制机制,减少页面间耦合,系统逻辑清晰。
3、 给单元测试和维护提供的有效的机制。
4、 提高系统中各种组件的可复用性。目前通常采用配置的方式提高组件的可复用性,一个标准的组件只要经过简单的配置即可应用在不同的系统中。
5、 减少培训的时间和成本。
目前对Web Tier Application 的设计模式主要有两种,它们是Microsoft的.NET ASP和Sun的Web Tier Application Framework。Sun的Web Tier Application Framework为JSP和Servelet的Web编程提供了较好的解决方案。
对两种模式优略的比较,非我的能力所及,也不是本文讨论的要旨。下面将着重讨论ASP.NET的设计模式。
将ASP.NET与传统的Windows应用程序来比较,将有助于建立良好的设计思路,这也是设计结构良好的ASP.NET应用的关键。Windows应用程序很好的解决了前面提出的问题,界面与逻辑的分离、中心控制机制、可以进行有效的单元测试等;最重要的是WebForm与Windows应用程序有太多的相似之处,你完全可以将许多以前的经验应用到WebForm中。
下图将ASP.NET与Windows应用程序对应起来将更易于对ASP.NET设计模式的理解。
由此可见:
这种设计模式利用到了page template 技术,具体实现如下图所示:
由于ASP.NET支持自定义的WebControl,可以实现<waf:header> <waf:bottom>, Microsoft 在其实现的PetStore中,有相应的实例代码这里将不再讨论。
下面就前文中提出的设计目标详细讨论ASP.NET的解决方案:
ASP.NET已很好的解决了这个问题,界面保存在*.aspx文件中,而事件的处理代码保存在*.aspx.cs中,可以在 *.aspx中用如下代码建立连接。
<%@ Page language="c#" Codebehind="waf_ctrl.aspx.cs" Inherits="waf.WAFControl" %>
在设计和实现 WebForm时,应尽量将代码放入 *.aspx.cs 中。
ASP.NET似乎没有提供一种中心控制机制,从Microsoft实现的PetStore中可以看出,页面之间的相互连接关系十分复杂,如下图所示,页面之间是一种网状关系。对于大型的应用系统此情况将会更加糟糕。Waf提供的中心控制机制,下一章将着重介绍。
WebForm的事件驱动机制,已经将各个功能单元的耦合减到最小。如比较常见的用户注册功能,你可以将用户的注册界面、信息填写、审核、在数据库中的保存等功能,在一个*.aspx 、aspx.cs和 *.cs中完成,就如同在传统的Dialog 中一样,这将使系统更加易于测试。
ASP.NET为开发常见标准组件提供了良好的基础。在系统设计中应设计、实现更多的标准组件,并通过配置的方式使其更加标准化。
如果你熟悉传统的Windows窗口编程技术,你会发现以前的很多经验可以应用到 ASP.NET中。
Web Application Framework(WAF)是一种基于ASP.NET的软件体系结构。其提供一种中心控制机制不但可以使系统逻辑清晰,代码易于维护,其还有如下益处:
1、 系统功能易于扩展
2、 支持集中身份认证
3、 易于授权
4、 易于审计
WAF采用 Mediator 和 Command 设计模式,实现了一种标准的可配置的控制组件,此种设计模式可使让.NET在MVC的软件系统结构下更好的工作。使用此设计模式后整个Web应用将呈现如下结构:
其中
1、 Waf_ctrl.aspx是整个系统的唯一入口点
2、 Waf_ctrl.aspx 通过请求参数中的Cmd,确定处理请求的页面,并将请求转发给此页面。
3、 Cmd及执行Cmd的页面可以通过配置完成。
1、 Command
WAF采用Command的方式达到中心控制、避免页面间相互连接的目的。
对于每个页面,其所需要了解的就是命令,每个页面可以
1、 接受并执行命令。
2、 在<a href=”…”>或<Form action>中指定处理用户请求的命令
3、 直接发送命令。
如一个用户Login页面login.aspx
1、 首先其接受并执行Login命令,显示Login页面,其中Form编码如下
<form action=”main.aspx?cmd=Login”>
2、 当用户不是注册用户,并点击Register注册时,login.aspx需要在页面中指定处理注册请求的命令,如
< a href=”main.aspx?cmd=Register” >Login</a>
3、 当用户输入用户名和密码,并点击”Login”时,执行后台的LoginButton_Click,验证用户的合法性。
4、 当用户验证成功,需要向用户显示付款页面时(如在 Online-shopping 中),Login.aspx可以直接发送Checkout 命令:
waf.Mediator.ExcuteCommand(“Checkout”, …); // this class provide by waf
控制流将直接转移到相应的命令执行页面,将显示Checkout 页面。
对于Command 在Web Page中的标识和传递有多种方式,WAF采用了URL的方式。
2、 唯一入口点
WAF需要使用唯一入口点,来实施中心控制
配置唯一入口点有两种方式
1、 直接配置,如唯一入口点为main.aspx,在编写页面时,输入
<a href=”main.aspx?cmd=welcome&other_parameter=value”></a>
<form action = “main.aspx?cmd=login”>
采用这种方式,如果入口点改变将会带来极大的维护工作量。
2、 WAF方式,WAF提供了一套自定义控件,其隐藏了入口点的具体位置,并且保持了与HTML相应元素的语义:如
<waf:a href=”welcome?other_parameter=value”></waf:a>
<waf:from action=”login”> <waf:form>
这样入口点的位置与具体页面无关,并可随时改动。
3、 Command的配置与执行
WAF的关键所在是Command的配置与执行,WAF提供了waf.Mediator.Mediator类,及与其对应的 waf.control.xml,在waf.control.xml中可以对Command 及其执行页面的配置
<?xml version="1.0" encoding="utf-8" ?>
<Control>
<Default-page>web/Default.aspx</Default-page>
<Error-page>web/Default.aspx</Error-page>
<Command-Set>
<Command name="Welcome" Executor = "web/Default.aspx"></Command>
<Command name="Category" Executor = "web/Category.aspx"></Command>
</Command-Set>
</Control>
其中:
<Default-Page>指定了没有任何Cmd 命令时显示的页面。
<Error-page>指定了Cmd错误时显示的页面
<Command>中属性 name指定了命令的名字,属性Executor 指定了执行该命令的页面。
命令的执行过程如下:
在入口点aspx初始化时(Page_Init),调用
Mediator.Instance(strConfigFile, …);
在入口点aspx 的 Page_Load中,调用
Mediator.ProcessRequest(…);
Mediator.ProcessRequest将根据Cmd调用相应的命令执行页面。
WAF定义了基于ASP.NET系统的软件体系结构,其中肯定有许多不足之处,望感兴趣的有识之士,来信提出宝贵意见,共同切磋。
WAF的地址为 http://www.privacymask.com/waf/
Email: [email protected]
本文地址:http://com.8s8s.com/it/it45669.htm