点击一个Button,来看Duwamish7的总体层次
点击Duwamish7.0的查询按钮-Go,来总揽Duwamish的层次结构.
涉及的东西的页面层次 +Duwamish +bin -Duwamish7.BusinessFacade.dll -Duwamish7.BusinessRules.dll -Duwamish7.Common.dll -Duwamish7.DataAccess.dll -Duwamish7.SystemFramework.dll -Duwamish7.Web.dll +modules -searchmodule.ascx -searchmodule.ascx.cs -SearchResults.aspx -SearchResults.aspx.cs - default.aspx -default.aspx.cs |
(1)在Default.aspx所引用的Searchmodule.ascx上面输入你想查询条件,点击Button-Go
由Modules\searchmodule.ascx处理
public void SearchButton_Click(Object sender,EventArg e) { int index = SearchDropDownList.SelectedIndex; Response.Redirect((new StringBuilder(PageBase.UrlBase)) .Append("/searchresults.aspx?type=") .Append(index) .Append("&fullType=") .Append(Server.HtmlEncode(SearchDropDownList.Items[index].Text)) .Append("&text=") .Append(Server.UrlEncode(searchText)).ToString(), false); } |
转到SearchResults.aspx接收type,fulltype,text的Search参数并进行处理
Duwamish7.Common.Data.BookData.SearchTypeEnum searchEnumType; DataSet resultSet=null; searchEnumType= (Duwamish7.Common.Data.BookData.SearchTypeEnum)Int32.Parse(Request.QueryString["type"]); searchType=Request.QueryString["fulltype"].ToString(); searchText=Request.QueryString["text"].ToString(); if(searchText!=String.Empty) { resultSet=(newProductSystem()).GetSearchItems(searchEnumType,searchText); } |
注释: 上面的过程是在Duwamish的Web表现层发生的动作,Web表现层就是aspx页面以及相应的aspx.cs代码. 看看这个Web表现成涉及到的命名空间(即Duwamish的层次): (1)Duwamish7.Common 这个命名空间不是Duwamish四层架构之一,它定义了一些全局性数据类型,以及一些配置数据,这些数据可以在各个层次调用. 关于图中的那些Common.Data的用途,下面有讨论. DuwamishConfiguration就是一些全局性的配置数据. (2)业务外观层Business Facade里面的函数: Duwamish7.BusinessFacade.GetSearchItems(BookData.SearchTypeEnum searchType,String searchText) Web表现层通常会: using Duwamish7.BusinessFacade;//业务外观 using Duwamish7.Common; using Duwamish7.Common.Data;// using Duwamish7.SystemFramework;// 不会 从而实现Web表现与数据访问的低耦合特性. |
(2)紧接着上面,调用Duwamish7.BusinessFacade.GetSearchItems(BookData.SearchTypeEnum searchType,String searchText)获得一个返回的DataSet;
{ ApplicationAssert.CheckCondition(searchText != String.Empty, "searchText is required", ApplicationAssert.LineNumber); using (Books bookDataAccess = new Books()) { BookData retVal = null; switch (searchType) { case BookData.SearchTypeEnum.Author: retVal = bookDataAccess.GetBooksByAuthor(searchText); break; case BookData.SearchTypeEnum.ISBN: retVal = bookDataAccess.GetBooksByISBN(searchText); break; case BookData.SearchTypeEnum.Subject: retVal = bookDataAccess.GetBooksBySubject(searchText); break; case BookData.SearchTypeEnum.Title: retVal = bookDataAccess.GetBooksByTitle(searchText); break; default: ApplicationAssert.Check(false, string.Format("searchType {0} is not valid", searchType.ToString()), ApplicationAssert.LineNumber); break; } return retVal; } } |
注释: Duwamish7的BusinessFacade结构: 这段业务外观层代码涉及所涉及的命名空间 (1)Duwamish7.SystemFramework SystemFramework项目包含一些application需要的配置参数,ApplicationLog日志类和ApplicationAssert参数校验类。SystemFramework项目为所有其他的项目所引用。(引用) (2)数据访问层 调用Duwamish7.DataAccess.Books的 GetBooksByAuthor(searchText); GetBooksByISBN(searchText); GetBooksBySubject(searchText); GetBooksByTitle(searchText); 业务外观层一般会: using Duwamish7.Common.Data; using Duwamish7.DataAccess;//数据访问层 using Duwamish7.SystemFramework; |
(3)又调Duwamish7.DataAccess.Books的
GetBooksByAuthor(searchText);
GetBooksByISBN(searchText);
GetBooksBySubject(searchText);
GetBooksByTitle(searchText);
public BookData GetBooksByAuthor(String searchText) { return FillBookData("GetBooksByAuthor", "@Author", searchText ); } private BookData FillBookData(String commandText, String paramName, String paramValue) { if (dsCommand == null ) { throw new System.ObjectDisposedException( GetType().FullName ); } BookData data = new BookData(); SqlCommand command = dsCommand.SelectCommand; command.CommandText = commandText; command.CommandType = CommandType.StoredProcedure; // use stored proc for perf SqlParameter param = new SqlParameter(paramName, SqlDbType.NVarChar, 255); param.Value = paramValue; command.Parameters.Add(param); dsCommand.Fill(data); return data; } |
注释: 我想有这方面的原因,你可以在定义BookData时候完全控制数据,比如,你可以对两个Column的数据进行运算,从而可以返回额外的更加实用的数据段,有的时候必须这样做,例如你想把多个Column的数据组合成为一个多参数的查询URL,而这些数据要帮定到DataGrid的超级链接列(当然,在存储过程也可以做到). |
总结:
这里显然没有涉及到业务规则层(BusinessRelus),这里引用卢彦的Duwamish深入剖析-结构篇
比较令人困惑的是其中的业务外观层和业务规则层,很多人在学习N层结构开发的时候,听得最多的是三层结构,分别为:表示层,中间层和数据层。Duwamish的WEB层和数据访问层比较好理解,也就是传统意义上的表示层和数据层,那么业务外观层和业务规则层和我们熟悉的中间层有什么联系呢? 设计思想: 在Web应用程序中,有部分操作只是简单的从数据库根据条件提取数据,不需要经过任何处理,而直接将数据显示到网页上,比如查询某类别的图书列表。而另外一些操作,比如计算定单中图书的总价并根据顾客的级别计算回扣等等,这部分往往有许多不同的功能的类,操作起来也比较复杂。我们可以先想象一下,如果我们采用三层结构,这些商业逻辑一般是会放在中间层,那么对内部的这些大量种类繁多,使用方法也各异的不同的类的调用任务,就完全落到了表示层。这样势必会增加表示层的代码量,将表示层的任务复杂化,和表示层只负责接受用户的输入并返回结果的任务不太相称,并增加了层与层之间的耦合程度。 |
======
我写的东西实在太潦草......