中文字幕二区_国产精品免费在线观看_黄色网站观看_人人草人人澡_日本真实娇小xxxx

您的位置: 首頁 > 技術(shù)文檔 > 網(wǎng)絡(luò)編程 > 面向?qū)ο蟮膽?yīng)用服務(wù)層設(shè)計
用Asp隱藏文件路徑,實現(xiàn)防盜鏈 回到列表 淺談 ASP 模板技術(shù)之參數(shù)傳遞
 面向?qū)ο蟮膽?yīng)用服務(wù)層設(shè)計

作者:孫亞民 時間: 2004-02-20 文檔類型:原創(chuàng) 來自:賽迪網(wǎng)

前言

  N層的應(yīng)用軟件系統(tǒng),由于其眾多的優(yōu)點,已經(jīng)成為典型的軟件系統(tǒng)架構(gòu),也已經(jīng)為廣大開發(fā)人員所熟知。在一個典型的三層應(yīng)用軟件系統(tǒng)中,應(yīng)用系統(tǒng)通常被劃分成以下三個層次:數(shù)據(jù)庫層、應(yīng)用服務(wù)層和用戶界面層。如下圖所示:

  其中,應(yīng)用服務(wù)層集中了系統(tǒng)的業(yè)務(wù)邏輯的處理,因此,可以說是應(yīng)用軟件系統(tǒng)中的核心部分。軟件系統(tǒng)的健壯性、靈活性、可重用性、可升級性和可維護(hù)性,在很大程度上取決于應(yīng)用服務(wù)層的設(shè)計。因此,如何構(gòu)建一個良好架構(gòu)的應(yīng)用服務(wù)層,是應(yīng)用軟件開發(fā)者需要著重解決的問題。

  為了使應(yīng)用服務(wù)層的設(shè)計達(dá)到最好的效果,我們通常還需要對應(yīng)用服務(wù)層作進(jìn)一步的職能分析和層次細(xì)分。很多開發(fā)者在構(gòu)建應(yīng)用服務(wù)層的時候,把數(shù)據(jù)庫操縱、業(yè)務(wù)邏輯處理甚至界面顯示夾雜在一起,或者,把業(yè)務(wù)邏輯處理等同于數(shù)據(jù)庫操縱,等等,這些,都是有缺陷的做法。本文,就在這個方面進(jìn)行設(shè)計時可采用的方案進(jìn)行一些探討。

  為了使討論更具有針對性,本文會討論一些比較流行的系統(tǒng)架構(gòu),例如J2EE架構(gòu),以及JDO。在微軟的.Net平臺上,將以Websharp中間件為例。Websharp中間件是筆者開發(fā)的一個構(gòu)建在微軟.Net平臺之上的一個中間件系統(tǒng),也是實現(xiàn)文章所述的系統(tǒng)架構(gòu)的支撐系統(tǒng)。選用這些架構(gòu)做例子,也是因為.Net出現(xiàn)的時間比較短,目前在這個平臺上沒有成熟統(tǒng)一的架構(gòu),而J2EE是目前最成熟的構(gòu)建企業(yè)應(yīng)用的平臺。

  自本人的《利用.Net框架開發(fā)應(yīng)用系統(tǒng)》和《實戰(zhàn)揭秘:開發(fā).Net平臺應(yīng)用系統(tǒng)框架》兩篇文章發(fā)表以來,收到很多反饋和來信,提出了很多問題。因為時間的關(guān)系,不能一一回復(fù),因此,也借本文給大家一些解答。需要說明的是,原來的Jobsinfo現(xiàn)在已經(jīng)做了升級,名稱變更為Websharp。

  設(shè)計的原則和評判標(biāo)準(zhǔn)

  同軟件工程的原則一樣,應(yīng)用服務(wù)層的設(shè)計,必須遵循的最重要的原則就是高內(nèi)聚和低耦合。軟件分層的本來目的,就是提高軟件的可維護(hù)性和可重用性,而高內(nèi)聚和低耦合正是達(dá)成這一目標(biāo)必須遵循的原則。盡量降低系統(tǒng)各個部分之間的耦合度,是應(yīng)用服務(wù)層設(shè)計中需要重點考慮的問題。

  內(nèi)聚和耦合,包含了橫向和縱向的關(guān)系。功能內(nèi)聚和數(shù)據(jù)耦合,是我們需要達(dá)成的目標(biāo)。橫向的內(nèi)聚和耦合,通常體現(xiàn)在系統(tǒng)的各個模塊、類之間的關(guān)系,而縱向的耦合,體現(xiàn)在系統(tǒng)的各個層次之間的關(guān)系。

   系統(tǒng)的框架,通常包含了一系列規(guī)范、約定和支撐類庫、服務(wù)。

  對于如何判斷一個軟件的系統(tǒng)框架的優(yōu)劣,筆者認(rèn)為,可以從以下幾個方面來評判:

  ◆ 系統(tǒng)的內(nèi)聚和耦合度

  這是保證一個系統(tǒng)的架構(gòu)是否符合軟件工程原則的首要標(biāo)準(zhǔn)。

  ◆ 層次的清晰和簡潔性

  系統(tǒng)每個部分完成功能和目標(biāo)必須是明確的,同樣的功能,應(yīng)該只在一個地方實現(xiàn)。如果某個功能可以在系統(tǒng)不同的地方實現(xiàn),那么,將會給后來的開發(fā)和維護(hù)帶來問題。

  系統(tǒng)應(yīng)該簡單明了,過于復(fù)雜的系統(tǒng)架構(gòu),會帶來不必要的成本和維護(hù)難度。在盡可能的情況下,一個部分應(yīng)該完成一個單獨并且完整的功能。

  ◆ 易于實現(xiàn)性

  如果系統(tǒng)架構(gòu)的實現(xiàn)非常困難,甚至超出團(tuán)隊現(xiàn)有的技術(shù)能力,那么,團(tuán)隊不得不花很多的精力用于架構(gòu)的開發(fā),這對于整個項目來說,可能會得不償失。簡單就是美。

  ◆ 可升級和可擴充性

  一個系統(tǒng)框架,受設(shè)計時技術(shù)條件的限制,或者設(shè)計者本人對系統(tǒng)認(rèn)識的局限,可能不會考慮到今后所有的變化。但是,系統(tǒng)必須為將來可能的變化做好準(zhǔn)備,能夠在今后,在目前已有的基礎(chǔ)上進(jìn)行演進(jìn),但不會影響原有的應(yīng)用。接口技術(shù),是在這個方面普遍應(yīng)用的技巧。

  ◆ 是否有利于團(tuán)隊合作開發(fā)

  一個好的系統(tǒng)架構(gòu),不僅僅只是從技術(shù)的角度來看,而且,它還應(yīng)該適用于團(tuán)隊開發(fā)模型,可以方便一個開發(fā)團(tuán)隊中各個不同角色的互相協(xié)作。例如,將Web頁面和業(yè)務(wù)邏輯組件分開,可是使頁面設(shè)計人員和程序員的工作分開來同步進(jìn)行而不會互相影響。

  ◆ 性能

  性能對于軟件系統(tǒng)來說是很重要的,但是,有的時候,為了能讓系統(tǒng)得到更大的靈活性,可能不得不在性能和其他方面取得平衡。另外一個方面,由于硬件技術(shù)的飛速發(fā)展和價格的下降,性能的問題往往可以通過使用使用更好的硬件來獲得提升。

  應(yīng)用服務(wù)層的內(nèi)容

  應(yīng)用服務(wù)層,通常也被稱為業(yè)務(wù)邏輯層,因為這一層,是應(yīng)用軟件系統(tǒng)業(yè)務(wù)邏輯處理集中的部分。然而,我將這一層稱為應(yīng)用服務(wù)層,而不稱業(yè)務(wù)邏輯層,因為,這一層需要處理的不僅僅是業(yè)務(wù)邏輯,還包含了其他方面的內(nèi)容。

  從完整的角度來說,應(yīng)用服務(wù)層需要處理以下內(nèi)容:

  ◆ 數(shù)據(jù)的表示方式

  數(shù)據(jù),是軟件處理的對象。從某種程度上來說,"軟件,就是數(shù)據(jù)結(jié)構(gòu)加算法"的說法,是有一定意義的。在面向?qū)ο蟮南到y(tǒng)中,數(shù)據(jù)是用類來表示的,代表了現(xiàn)實世界實體對象在軟件系統(tǒng)中的抽象?紤]所謂的MVC模式,這個部分的類屬于M--實體類的范疇。由于應(yīng)用軟件通常會使用數(shù)據(jù)庫,數(shù)據(jù)庫中的數(shù)據(jù),可以看成是對象的持久化保存。由于數(shù)據(jù)庫一般是關(guān)系型的,因此,這個部分,還需要考慮類(對象)同關(guān)系型數(shù)據(jù)的映射,即通常所說的O-R MAP問題。

  ◆ 數(shù)據(jù)的存取方式

  如同上述所說,軟件系統(tǒng)處理的實體對象數(shù)據(jù)需要持久化保存數(shù)據(jù)庫中,因此,我們必須處理系統(tǒng)同數(shù)據(jù)庫的交互,以及數(shù)據(jù)的存取和轉(zhuǎn)換方式的問題。

  ◆ 業(yè)務(wù)邏輯的組織方式

  在面向?qū)ο蟮南到y(tǒng)中,業(yè)務(wù)邏輯表現(xiàn)為對象之間的交互。有了上述的實體對象,以及對象的保存策略,就可以將這些對象組合起來,編寫我們的業(yè)務(wù)邏輯處理程序。在業(yè)務(wù)邏輯的處理中,必須保證處理的正確性和完整性,這將會涉及到事務(wù)處理。通常,我們也會把業(yè)務(wù)邏輯封裝成組件的形式,以得到最大的可重用性。

  ◆ 業(yè)務(wù)服務(wù)的提供方式

  在我們完成系統(tǒng)的功能后,如何向客戶提供服務(wù),是我們需要考慮的問題。這里的客戶,不僅僅是指軟件的使用者,也包括調(diào)用的界面、其他程序等。例如,在一個基于Web的ASP.Net或JSP系統(tǒng)中,業(yè)務(wù)邏輯功能的客戶便是這些ASP.Net頁面或JSP頁面。業(yè)務(wù)邏輯組件應(yīng)該通過什么方式,直接的,或間接的,向這些客戶提供服務(wù),是這一層需要完成的任務(wù)。

  ◆ 層的部署和層間交互

  對于一個多層的應(yīng)用軟件系統(tǒng)來說,尤其是大型的應(yīng)用軟件系統(tǒng),通常需要把不同的部分部署在不同的邏輯或物理設(shè)備上。特別是一些基于Web的應(yīng)用軟件系統(tǒng),其部署工作將涉及到Web服務(wù)器、組件服務(wù)器、數(shù)據(jù)庫服務(wù)器等不同的服務(wù)設(shè)備。在進(jìn)行應(yīng)用軟件架構(gòu)的設(shè)計的時候,必須考慮各種不同的部署方案。

 

  綜上所述,一個完整的基于Web的應(yīng)用軟件系統(tǒng),其架構(gòu)可以用下圖來表示(Websharp推薦的應(yīng)用軟件系統(tǒng)架構(gòu)):

  對于以上各個方面來說,每個問題都可以有很多種策略和方案,但是,在一個系統(tǒng)中,應(yīng)該盡可能的統(tǒng)一這些策略和方案。也就是說,在一個系統(tǒng),或者一個項目中,應(yīng)該統(tǒng)一每個解決每個問題所采用的方法。軟件的開發(fā)方法是靈活的,可以用不同的方法解決相同的問題,這會誘使開發(fā)人員采用他們認(rèn)為能夠表現(xiàn)自己的方法,但是,從整個系統(tǒng)來看,這將會是災(zāi)難性的。我們應(yīng)該盡可能統(tǒng)一,就是,采用統(tǒng)一的數(shù)據(jù)表示方式、統(tǒng)一的數(shù)據(jù)存取方式、統(tǒng)一的業(yè)務(wù)邏輯處理方式等。

  下面,將就這些部分的設(shè)計策略和可用方案進(jìn)行一些比較詳細(xì)的論述。

  數(shù)據(jù)實體的表示

  應(yīng)用軟件系統(tǒng),從本質(zhì)上來說,是計算機對現(xiàn)實世界的模擬,F(xiàn)實世界中的實體對象,在軟件系統(tǒng)中,表現(xiàn)為需要處理的數(shù)據(jù)。在面向?qū)ο蟮南到y(tǒng)中,這是通過"類"和"對象"來表示的。

  參考著名的"MVC"模式,類可以分成實體類(M)、控制類(C)、和邊界類(V),分別代表了實體對象、控制和界面顯示。系統(tǒng)中需要處理的數(shù)據(jù),在面向?qū)ο蟮南到y(tǒng)中,屬于實體類部分。

  在考慮數(shù)據(jù)實體層的設(shè)計策略的時候,需要把握以下要點:

  ◆ 一致的數(shù)據(jù)表示方式。在一個系統(tǒng)中,數(shù)據(jù)的表示方式必須盡可能統(tǒng)一,同時,在處理單個數(shù)據(jù)和多個數(shù)據(jù)的時候,處理方式盡可能一致。

  ◆ 因為數(shù)據(jù)通常是需要存儲到數(shù)據(jù)庫中,因此,良好的映射方法是必需的。

  ◆ 處理好對象的粒度,即所謂的粗粒度對象、細(xì)粒度對象。

  一般例子

  考慮一個現(xiàn)實的例子,一個倉庫中的產(chǎn)品(Product),在系統(tǒng)中可以使用如下定義:

public class Product{public string Name;  //名稱
  public decimal Price;//價格
  public int Count;//數(shù)量
  }
  可以按照如下方法使用Product類:
  Product p=new Product();
  //……處理Product

  這是一個包含了三個屬性的Product類的定義。為了便于說明,在這里,我們盡量將問題簡化了。

   又例如,一張入庫單可以使用如下定義:

public class Form{public string ID;               //入庫單編號
public DateTime AddTime;      //入庫時間
public FormDetail[] FormDetails;  //入庫單明細(xì)
}
public class FormDetail
{
public Product InProduct;       //入庫產(chǎn)品
public int Count;              //入庫數(shù)量
}

  對于處理單個對象,通常采用上述的方法,但是,當(dāng)我們需要處理相同類的一組對象,也就是處理一個對象集合的時候,就會有一些小小的麻煩。

  如前所述,我們希望在處理單個對象和對象集合的時候,處理的方式盡量統(tǒng)一,這對于軟件開發(fā)的意義是很大的。常用的處理對象集合的方法有:

  ◆數(shù)組表示的方法

  例如,上面的例子中當(dāng)一張入庫單包含多條入庫單明細(xì)的時候采用的方法。為了靈活性,也可以使用容器來,如Java中的Vector或C#的ArrayList(C#)。只是,在處理對象的時候,需要一個類型轉(zhuǎn)換的操作。這個問題,在支持泛型的語言中不會存在,如使用C++的標(biāo)準(zhǔn)庫的容器類。

  ◆ObjectCollection方法。這個方法同上面的方法類似,不同之處在于,為每個實體類設(shè)計一個Collection類。例如,可以為FormDetail設(shè)計一個FormDetailsCollection類(C#):

public class FormDetailsCollection: ArrayList
{
public void Add(FormDetail detail)
{
base.Add(detail);
}
public new FormDetail this[int nIndex]
{
get{ return (FormDetail)base[nIndex];
}
}
}

  這么做的好處在于,在操作集合中的對象時,不必進(jìn)行類型轉(zhuǎn)換的操作。

  ◆數(shù)據(jù)集的表示方法。

  采用這種方法,通常是直接把從數(shù)據(jù)庫查詢中獲取的數(shù)據(jù)集(Recordset)作為數(shù)據(jù)處理對象。這種方法在ASP應(yīng)用程序中是非常常見的做法。這種做法簡單,初學(xué)者很容易掌握,但是弊病也很多。

  EJB的方法

  在J2EE體系中,對實體對象的處理的典型方法是Entity Bean。J2EE中使用Entity Bean來表示數(shù)據(jù),以及封裝數(shù)據(jù)的持久化儲存(同數(shù)據(jù)庫的交互)。由于Entity Bean比較消耗資源,而且采用的是遠(yuǎn)程調(diào)用的方式來訪問,因此,在需要傳遞大量數(shù)據(jù),或者在不同的層次之間傳遞數(shù)據(jù)的時候,往往還會采用一些諸如"值對象"(Value Object)的設(shè)計模式來提升性能。關(guān)于J2EE中的設(shè)計模式的更多內(nèi)容,讀者可以參考《J2EE核心模式》一書。

  JDO的方法

  相對于J2EE這個昂貴的方法來說,JDO提供了一個相對"輕量級"的方案。在JDO中,你可以采用一般的做法,編寫實體類,然后,通過一些強化器對這些類進(jìn)行強化,以使其符合JDO的規(guī)范,最后,你可以通過PersistenceManager來實現(xiàn)對象的持久化儲存。

  無論是EJB還是JDO,在同數(shù)據(jù)庫進(jìn)行映射的時候,都選用了XML配置文件的方式。這是一種靈活的方式。由于XML強大的表達(dá)能力,我們可以很好的用它來描述代碼中的實體類和數(shù)據(jù)庫之間的映射關(guān)系,并且,不用在代碼中進(jìn)行硬編碼,這樣,在情況發(fā)生變化的時候,有可能只需要修改配置文件,而不用去修改程序的源代碼。關(guān)于EJB和JDO的配置文件的更多的信息,各位可以參考相關(guān)的文檔,這里不再贅述了。

  然而,使用XML配置文件的方式并不是唯一的方法,在微軟提供的一些案例中,如Duwamish示例,就沒有采用這種方式。至于開發(fā)人員在開發(fā)過程中具體采用哪種方式,是需要根據(jù)具體情況進(jìn)行權(quán)衡和取舍的。

  Websharp的方法

  Websharp在數(shù)據(jù)的表現(xiàn)上,充分利用了.Net Framework類庫中DataSet的功能,設(shè)計了一個EntityData類。這個類繼承了DataSet,并增加了一些屬性和方法。同樣的,同數(shù)據(jù)庫的映射關(guān)系,也是采用XML配置文件的方式。

  在實際的應(yīng)用中,要獲取一個實體對象,可以通過如下方式取得:

EntityData Customer=EntityDataManager. GetEmptyEntity("Customer");

  然后,可以通過如下方式來訪問這個對象的屬性:

string CustomerID=Customer["CustomerID"]

  可以看到,這種方式同傳統(tǒng)的方式有點不同。在這種方式下,數(shù)據(jù)的表現(xiàn)形式只有一個,那就是EntityData。其好處是明顯的,不用為每個實體都單獨編寫一個類,能夠大大減少代碼的編寫量。其缺點也很明顯,那就是不能利用編譯器類型檢測的功能,如果在調(diào)用對象的屬性的時候,寫錯了屬性的名稱,就可能出錯,但是,這個問題可以通過工具來解決。

  關(guān)于這個方面更加詳細(xì)的信息,可以參見拙文:

  《利用.Net框架開發(fā)應(yīng)用系統(tǒng)》

  《實戰(zhàn)揭秘:開發(fā).Net平臺應(yīng)用系統(tǒng)框架》

  數(shù)據(jù)的存取方式

  數(shù)據(jù)存取的目的,是持久化保存對象,以備后來的使用,如查詢、修改、統(tǒng)計分析等。存取的對象,可以是數(shù)據(jù)庫、普通文件、XML甚至其他任何方式,只要保證數(shù)據(jù)能夠長久保存,并且,不會受斷電、系統(tǒng)重起等因素的影響。在這個部分,最理想的狀況,自然是能夠支持除了數(shù)據(jù)庫以外的各種類型的存取方式,或者,至少留有接口,能夠比較方便的擴充。

  因為數(shù)據(jù)庫是最常用,也是最有效的數(shù)據(jù)存儲方法,因此,支持?jǐn)?shù)據(jù)庫存儲是最首先必須支持的。在不同的平臺下,有不同的數(shù)據(jù)庫訪問的手段。例如,在Java平臺下,有JDBC,在Windows平臺下,可以使用ADO、ADO.Net等。但是,這些手段還比較接近底層,在實際操縱數(shù)據(jù)庫的時候,需要編寫大量的代碼,并且,我們還需要通過手工的方式來完成將程序中的面向?qū)ο蟮臄?shù)據(jù)存儲到關(guān)系型數(shù)據(jù)庫的工作。這么做,自然編程的效率不高,并且非常容易出錯。但是,不可否認(rèn),這也是一種可以選用的方式。

  從另外一個方面來看,由于我們前面已經(jīng)解決了數(shù)據(jù)的映射問題,因此,在數(shù)據(jù)的存取方面是非常有規(guī)律的,我們完全可以讓這個工作通過框架來執(zhí)行。這樣,我們一方面可以簡化很多同數(shù)據(jù)庫交互方面的代碼編寫工作量,能夠減少出現(xiàn)Bug的幾率,另一方面,由于框架封裝了不同數(shù)據(jù)庫之間的差異,使得我們在編寫程序的時候,不用考慮不同數(shù)據(jù)庫之間的差異,而將這個工作交給框架去做,實現(xiàn)軟件的后臺數(shù)據(jù)庫無關(guān)性。

  在這個部分,以下兩個部分的類會顯得特別重要:

  ◆對象--關(guān)系映射的分析類,能夠通過既定的方案完成對象--關(guān)系的映射,確定數(shù)據(jù)存取方案

  ◆數(shù)據(jù)庫操縱類:根據(jù)映射關(guān)系,將數(shù)據(jù)準(zhǔn)確的存儲到數(shù)據(jù)庫中,并且封裝不同數(shù)據(jù)庫之間的差異。

   這個部分的操作過程,可以用圖大概的表示如下:

  在J2EE中,這個部分比較典型的就是EntityBean中的CMP。由于在BMP中,同數(shù)據(jù)庫的交互部分需要通過手工編寫代碼的方式來實現(xiàn),因此,很難享受到容器帶來的便利,只是由于EJB2.0以前的標(biāo)準(zhǔn),CMP的功能,包括映射能力、實體關(guān)系模式等方面的功能比較弱,所以,在很多時候,我們不得不使用BMP,F(xiàn)在,EJB2.0,在這個方面的功能已經(jīng)非常強大了,我們完全可以享受容器帶來的便利,而將大部分精力放在實現(xiàn)更加復(fù)雜的業(yè)務(wù)邏輯方面了。

  在JDO中,您同樣可以通過PersistenceManager來實現(xiàn)同樣的目標(biāo),例如,您想把一個Customer對象保存到數(shù)據(jù)庫中,可以采用類似于下面的代碼:

Customer customer=new Customer(……);
PersistenceManager PM=PMFactory.initialize(……);
Pm.persist(customer);

   代碼同樣非常簡明和直觀,沒有一大堆數(shù)據(jù)庫操縱的代碼,也不容易發(fā)生差錯。

Websharp的方案

  Webshap為數(shù)據(jù)存取的類定義了IEntityDAO接口,該接口的定義如下:

public interface IEntityDAO
{
void InsertEntity(EntityData entity);
void UpdateEntity(EntityData entity);
void DeleteEntity(EntityData entity);
        EntityData FindByPrimaryKey(object KeyValue);
}

 對于每一個實體類,可以通過擴展這個接口來實現(xiàn)數(shù)據(jù)訪問的類。但是,由于這個接口沒有提供任何實現(xiàn)方法,因此,到具體每個實現(xiàn)類的時候,如果是直接擴展自這個接口,實現(xiàn)的代碼還必須手工填寫。為了提高開發(fā)效率,減少代碼編寫量和出現(xiàn)Bug的可能性,框架提供了AbstractSingleTableDAO和AbstractMultiTableDAO.cs類,這兩個類擴展自IEntityDAO,分別實現(xiàn)了針對單個數(shù)據(jù)庫表和多個數(shù)據(jù)庫表的數(shù)據(jù)庫訪問方法,并且,實現(xiàn)了IDisposable接口。這樣,我們在實際編寫代碼的時候,只需要繼承自這兩個類就可以了。 例如,Customer類的數(shù)據(jù)存取類可以定義如下:

 public class CustomerEntityDAO:AbstractSingleTableDAO

 然后,就可以在代碼中這么使用:

 Customer customer=......
using(CustomerEntityDAO CDO=new CustomerEntityDAO())
{
CDO.UpdateEntity(customer);
}

  更加一般的,Wensharp也提供了PersistenceManager類,可以用于將EntityData中的數(shù)據(jù)存入數(shù)據(jù)庫。這個類包含了兩個方法:PersistEntity和DeleteEntity。如果不想為某個實體類編寫專門的DAO類,那么,也可以使用這個類來操縱實體對象。不過,目前,只支持映射成單個表的對象的自動存貯。下面是一個例子:

 PersistenceManager
pm=PersistenceManager.Initial();
pm. PersistEntity(entity);

為了封裝不同數(shù)據(jù)庫的操作,統(tǒng)一的數(shù)據(jù)庫訪問接口是必須的。關(guān)于編寫通用數(shù)據(jù)庫訪問類的內(nèi)容,可以參見拙作:《使用設(shè)計模式構(gòu)建通用數(shù)據(jù)庫訪問類》。

  在這個部分,另外需要注意的是,為了保證數(shù)據(jù)存儲的完整性,應(yīng)當(dāng)考慮事務(wù)處理的功能。J2EE、JDO和Websharp都支持在數(shù)據(jù)存儲的時候使用事務(wù)處理。

業(yè)務(wù)邏輯的處理

  有了上面的工作,我們就可以把這些對象組合起來,編寫我們的業(yè)務(wù)邏輯。在面向?qū)ο蟮南到y(tǒng)中,業(yè)務(wù)邏輯表現(xiàn)為對象之間的交互。在一些簡單的系統(tǒng)中,沒有復(fù)雜的業(yè)務(wù)邏輯,只是一些數(shù)據(jù)的維護(hù)工作,那么,有了上面兩個部分的工作,我們實際上可能已經(jīng)忘成了大部分的工作。

  在這個部分,由于不同系統(tǒng)之間業(yè)務(wù)邏輯千差萬別,基本上沒有辦法提供統(tǒng)一的模式。但是,應(yīng)當(dāng)注意的是,在同一個系統(tǒng)中,采用基本一致的策略是非常必要的,這有助于消除項目內(nèi)部的不一致性,使項目更加可控。甚至于,這些策略可以擴展成公司部分、甚至所有項目的策略。

  值得指出的是,很多人在這個部分操縱數(shù)據(jù)庫,把業(yè)務(wù)邏輯處理等同于數(shù)據(jù)庫操作,這是不可取的。在業(yè)務(wù)邏輯處理中,處理的應(yīng)該是對象,而不是直接同數(shù)據(jù)庫打交道,這樣,才能獲得更好的系統(tǒng)結(jié)構(gòu)。   在業(yè)務(wù)邏輯處理部分,由框架提供一些支撐的服務(wù)是非常必要的。這其中,最重要的一點就是事務(wù)的處理。業(yè)務(wù)邏輯的處理過程,會涉及到多個對象之間的交互,以及多次同數(shù)據(jù)庫的交互。為了保證處理過程的完整性,必須使用事務(wù)處理的方法?蚣鼙仨氈С质聞(wù)處理。

  事務(wù)處理的功能,基本上有兩種選擇:使用基于數(shù)據(jù)庫連接的事務(wù)、使用外部事物處理服務(wù)。

  使用基于數(shù)據(jù)庫連接的事務(wù),事務(wù)處理的性能相對比較高,但是,當(dāng)系統(tǒng)涉及到多個數(shù)據(jù)庫之間的交互時,基于數(shù)據(jù)庫連接的事務(wù)便無能為力了。而使用專用的事務(wù)處理服務(wù),能夠適應(yīng)更多的情況,并且,有測試表明,隨著數(shù)據(jù)處理量的上升,兩者之間的性能差異會逐漸減小。

  在J2EE中,容器提供了事務(wù)處理的能力。在.Net平臺上,事務(wù)處理是通過Windows COM+服務(wù)來提供的。在Websharp中,對COM+服務(wù)做了一個簡單的封裝。同時,也能夠使用基于數(shù)據(jù)庫連接的事務(wù)。

  下面是一個簡單的例子,表示了一張入庫單入庫的過程,在這個過程中,需要修改入庫單上每種產(chǎn)品的現(xiàn)有庫存量:

public void StoreIntoWarehouse(EntityData insertForm)
{
insertForm.SetCurrentTable("FormDetail");
TransactionManager transManager=new TransactionManager();
ProductEntityDAO productDAO=new ProductEntityDAO(true);
FormEntityDAO formDAO=new FormEntityDAO(true);
try
{
if(insertForm.CurrentTable.Rows.Count>0)
do
{
string productID=insertForm["ProductID"].ToString();
decimal inCount=insertForm.GetDecimal("InCount");
EntityData product=productDAO.FindByPrimaryKey(productID);
product["CurrentCount"]=product.GetDecimal("CurrentCount")+inCount;
transManager.AddMethod(
new TransactionManagedFunction(productDAO.UpdateEntity),product);
}while(insertForm.Next());
transManager.AddMethod(
new TransactionManagedFunction(formDAO.InsertEntity),insertForm);
transManager.ExecuteMethods();
}
catch(Exception ee)
{
throw ee;
}
finally
{
productDAO.Dispose();
insertForm.Dispose();
}
}

  業(yè)務(wù)服務(wù)的提供

  業(yè)務(wù)外觀層(Business Facade)的目的,是隔離系統(tǒng)功能的提供者和使用者,更明確地說,是隔離業(yè)務(wù)邏輯的軟件的用戶界面(可以參見Facade設(shè)計模式)。這一層沒有任何需要處理的邏輯,只是作為后臺邏輯處理和前端用戶界面的緩沖區(qū),以達(dá)到如下目的

  ◆將用戶界面和系統(tǒng)業(yè)務(wù)邏輯處理分開,這樣,當(dāng)業(yè)務(wù)邏輯發(fā)生變化時,不用修改客戶端程序,是一種支持變化的設(shè)計方法。

  ◆使同一個業(yè)務(wù)邏輯能夠處理不同的客戶端請求。例如,可以將Facade設(shè)計成Web Service,這樣,可以同時為傳統(tǒng)的WinForm客戶端程序、Web程序以及其他外部系統(tǒng)提供服務(wù),而使用相同的應(yīng)用服務(wù)層,同時,也可以實現(xiàn)系統(tǒng)的分布式部署。關(guān)于如何做到這一點,可以參見本文所附的Demo程序。

  ◆作為系統(tǒng)不同模塊之間的調(diào)用接口。一個系統(tǒng)通常會包含很多模塊,這些模塊相對獨立,又可能互相調(diào)用。為了減少各個不同部分之間的耦合度,必須采用一定的設(shè)計方法,F(xiàn)acade設(shè)計模式就是非常有效的一種,也是業(yè)務(wù)外觀層的基礎(chǔ)。

  ◆有利于項目團(tuán)隊的分工協(xié)作。業(yè)務(wù)外觀層作為一個訪問接口,將界面設(shè)計人員和邏輯設(shè)計人員分開,使得系統(tǒng)的開發(fā)可以實現(xiàn)縱向的分工,不同的開發(fā)人員可以關(guān)注自己的領(lǐng)域而不會受到干擾。

   業(yè)務(wù)外觀層的代碼框架,在系統(tǒng)分析和設(shè)計完成后就可以完成,他需要提供的方法,就相當(dāng)于在界面設(shè)計人員和邏輯設(shè)計人員之間簽訂了一個協(xié)議,他雖然沒有實現(xiàn)任何邏輯,但是,他的引入,能使系統(tǒng)的開發(fā)更加有條理,更加簡明。套用《設(shè)計模式》上的一句話,就是,"任何問題,都可以通過引入一個中間層來得到簡化"。

   剪裁和取舍

   以上四個層次,對于大型的應(yīng)用軟件系統(tǒng)來說,是非常必要的。但是,對于一些小型的應(yīng)用軟件系統(tǒng),如果完全按照以上的層次來做,可能反而會影響工作效率。因此,針對不同的系統(tǒng),可以對架構(gòu)進(jìn)行一定的剪裁。

  數(shù)據(jù)實體層和實體控制層,是每個應(yīng)用軟件系統(tǒng)所必需的,顯然無法裁減。對于業(yè)務(wù)邏輯層和業(yè)務(wù)外觀層,根據(jù)實體情況,可以進(jìn)行如下裁減:

  ◆如果系統(tǒng)沒有復(fù)雜的業(yè)務(wù)邏輯,而只是一些數(shù)據(jù)的操作,或者業(yè)務(wù)邏輯特別少,那么,可以省略業(yè)務(wù)邏輯層,而將相關(guān)的功能移至實體控制層。

  ◆如果不考慮多種客戶端的情況,也不考慮分布式部署的問題,系統(tǒng)的模塊又很少,不會產(chǎn)生模塊間緊耦合的情況,那么,可以不使用業(yè)務(wù)外觀層,而讓用戶界面程序直接訪問業(yè)務(wù)功能。

  在上面的論述中,對于每個層次,都說明了可以選擇的多種方案,每一種方案都有他的優(yōu)點和缺點,在具體開發(fā)的過程中,需要根據(jù)具體情況加以取舍。

  系統(tǒng)外的話

  應(yīng)用軟件系統(tǒng)架構(gòu),是軟件工程的重要組成部分。設(shè)計一個好的框架,其目的很明確,那就是,在目前還沒有"銀彈"之前,盡最大的可能,提高軟件開發(fā)的效率和軟件質(zhì)量,把不必要的工作和容易出錯的工作,交給框架去處理。

  應(yīng)用服務(wù)層,在軟件系統(tǒng)中,是一個非常復(fù)雜的部分,乍看之下,沒有任何規(guī)律可行,給人無從下手的感覺。我們的目標(biāo),就是盡量化無規(guī)律為有規(guī)律,把有規(guī)律的東西提取出來,形成規(guī)范,從而減少今后的開發(fā)工作量。其方法,就是對系統(tǒng)進(jìn)行合理的分層,這樣,系統(tǒng)的層次清晰了,每個層次完成的功能就比較單一,就意味著每個層次的都相對更有規(guī)律可循,這樣,我們就可以把這些有規(guī)律的東西交給框架去執(zhí)行,或者,開發(fā)一個輔助工具,來完成這部分的代碼編寫工作。Websharp就提供了這樣一個代碼自動生成的工具。這個工具被設(shè)計成Visual Studio.Net集成開發(fā)環(huán)境的插件,在實際開發(fā)過程中,能夠提供很多便利。這是系統(tǒng)層次清晰帶來的另外一個好處。

  對于一個軟件公司來說,統(tǒng)一的系統(tǒng)框架的意義不僅僅在于軟件開發(fā)的本身。一個統(tǒng)一的系統(tǒng)框架,也是公司知識管理的重要組成部分。公司如果有一個或有限個數(shù)的明確的軟件框架,那么,這些框架就可以成為凝結(jié)公司開發(fā)人員經(jīng)驗、智慧的載體,并且可以在不斷的實踐中加以充實和完善。由于公司的軟件系統(tǒng)的框架比較統(tǒng)一,那么當(dāng)某個項目更換或增加開發(fā)人員的時候,后來的人也能夠比較容易接手,這對于公司的開發(fā)管理是具有非常重要的意義的。

  關(guān)于系統(tǒng)框架同知識管理的關(guān)系的內(nèi)容,因為不是本文的重點,限于篇幅的關(guān)系,所以不再贅述,會另文加以說明。

  結(jié)語

  應(yīng)用軟件系統(tǒng)的應(yīng)用服務(wù)層是非常復(fù)雜的,為了使得系統(tǒng)的結(jié)構(gòu)更加清晰,找出其中規(guī)律性的東西,就需要我們對系統(tǒng)做進(jìn)一步的層次劃分。對于每個層次,都可以有多種設(shè)計的策略,每一種策略都不可能做到盡善盡美,這就需要我們在實際中加以取舍。

  限于本人的認(rèn)識和水平,文章中所說觀點和方法或有不當(dāng)之處,還請大家能夠指教,一起探討。

  附:使用Websharp中間件開發(fā)的Demo程序一份。

  作者簡介:孫亞民,1998年畢業(yè)于南京大學(xué),目前中國科技大學(xué)碩士再讀,蘇州某軟件公司技術(shù)總監(jiān),可以通過sunny_y_m@163.com 同他聯(lián)系。

出處:賽迪網(wǎng)
責(zé)任編輯:cjj

◎進(jìn)入論壇網(wǎng)絡(luò)編程版塊參加討論

相關(guān)文章
[asp.net]C#教程
常見 Datagrid 錯誤
進(jìn)入 ASP.NET 世界
解讀 C# 中的正則表達(dá)式
關(guān)鍵字搜索 常規(guī)搜索 推薦文檔
熱門搜索:CSS Fireworks 設(shè)計比賽 網(wǎng)頁制作 web標(biāo)準(zhǔn) 用戶體驗 UE photoshop Dreamweaver Studio8 Flash 手繪 CG
站點最新 站點最新列表
周大!熬•自然”設(shè)計大賽開啟
國際體驗設(shè)計大會7月將在京舉行
中國國防科技信息中心標(biāo)志征集
云計算如何讓安全問題可控
云計算是多數(shù)企業(yè)唯一擁抱互聯(lián)網(wǎng)的機會
阿里行云
云手機年終巨獻(xiàn),送禮標(biāo)配299起
阿里巴巴CTO王堅的"云和互聯(lián)網(wǎng)觀"
1499元買真八核 云OS雙蛋大促
首屆COCO桌面手機主題設(shè)計大賽
欄目最新 欄目最新列表
淺談JavaScript編程語言的編碼規(guī)范
如何在illustrator中繪制臺歷
Ps簡單繪制一個可愛的鉛筆圖標(biāo)
數(shù)據(jù)同步算法研究
用ps作簡單的作品展示頁面
CSS定位機制之一:普通流
25個最佳最閃亮的Eclipse開發(fā)項目
Illustrator中制作針線縫制文字效果
Photoshop制作印刷凹凸字體
VS2010中創(chuàng)建自定義SQL Rule

藍(lán)色理想版權(quán)申明:除部分特別聲明不要轉(zhuǎn)載,或者授權(quán)我站獨家播發(fā)的文章外,大家可以自由轉(zhuǎn)載我站點的原創(chuàng)文章,但原作者和來自我站的鏈接必須保留(非我站原創(chuàng)的,按照原來自一節(jié),自行鏈接)。文章版權(quán)歸我站和作者共有。

轉(zhuǎn)載要求:轉(zhuǎn)載之圖片、文件,鏈接請不要盜鏈到本站,且不準(zhǔn)打上各自站點的水印,亦不能抹去我站點水印。

特別注意:本站所提供的攝影照片,插畫,設(shè)計作品,如需使用,請與原作者聯(lián)系,版權(quán)歸原作者所有,文章若有侵犯作者版權(quán),請與我們聯(lián)系,我們將立即刪除修改。

您的評論
用戶名:  口令:
說明:輸入正確的用戶名和密碼才能參與評論。如果您不是本站會員,你可以注冊 為本站會員。
注意:文章中的鏈接、內(nèi)容等需要修改的錯誤,請用報告錯誤,以利文檔及時修改。
不評分 1 2 3 4 5
注意:請不要在評論中含與內(nèi)容無關(guān)的廣告鏈接,違者封ID
請您注意:
·不良評論請用報告管理員,以利管理員及時刪除。
·尊重網(wǎng)上道德,遵守中華人民共和國的各項有關(guān)法律法規(guī)
·承擔(dān)一切因您的行為而直接或間接導(dǎo)致的民事或刑事法律責(zé)任
·本站評論管理人員有權(quán)保留或刪除其管轄評論中的任意內(nèi)容
·您在本站發(fā)表的作品,本站有權(quán)在網(wǎng)站內(nèi)轉(zhuǎn)載或引用
·參與本評論即表明您已經(jīng)閱讀并接受上述條款
推薦文檔 | 打印文檔 | 評論文檔 | 報告錯誤  
專業(yè)書推薦 更多內(nèi)容
網(wǎng)站可用性測試及優(yōu)化指南
《寫給大家看的色彩書1》
《跟我去香港》
眾妙之門—網(wǎng)站UI 設(shè)計之道
《Flex 4.0 RIA開發(fā)寶典》
《贏在設(shè)計》
犀利開發(fā)—jQuery內(nèi)核詳解與實踐
作品集 更多內(nèi)容

雜⑦雜⑧ Gold NORMANA V2