很多人都研究過petshop,我開始認識分層架構也是從研究這個petshop開始的。但是我發現很多人一談三層架構就是
petshop那一套東西。實體類,DAL,BLL那一套東西。首先我不否認petshop這個架構整體的設計的合理性。但是這個合理性也是在一
定的項目環境下來說的。我覺得petshop這個架構只適合比較小的項目。系統的大部分需求只是對資料庫的CRUD操作。而且商務邏輯
變化變化可能性很小的情況。
看過企業架構模式的應該知道。Petshop這個商務邏輯層採用的是表模組(table module),一個表對應一個類,負責這個表
相關的商務邏輯。資料訪問層是表入口(table gateway),也是一個表對一個類,負責這個表的所有crud操作。還定義了實體類用
來儲存資料庫中取出的資料,用來在各層間傳遞。這種設計資料和行為分別放到了不同的類中。這個確實違背了oo的原則(資料和
資料相關的行為應該放到一起).商務邏輯層中商務邏輯操作類還都是靜態方法。
從以上分析可以看出這個架構的一大隱患就是把自己弄的和oo保持了很遠的距離。首先是行為和資料的分離。再者就是商務邏輯類
中的靜態方法。這些都讓oo的核心特性,繼承和多態沒辦法應用。沒了oo,設計模式中那些封裝變化點的手法也就派不上用處了。
做公司專屬應用程式的一定都有體會,變化那個快啊!唯一不變的就是變化。想給petshop想幾個需求變化來說明這個架構不適合複雜業務邏
輯項目,還真是不容易。乾脆就拿我現在面對的項目說事吧。這個是我們公司的網站。主要是賣我們公司的產品。基本的商務程序是
,使用者填寫一些和產品相關的資訊。連絡人,郵箱,地址等等。然後處理訂單的流程如下。1.根據使用者選擇的產品做不同的驗證(
因為不同產品的需要的驗證的資料項目和驗證規則都不一樣)。2.根據不同的產品計算價格3根據不同的產品調用庫存系統介面.(主
要是傳遞的參數不一樣)。4.根據不同產品的儲存訂單資訊和產品資訊。目前系統的設計基本這樣的。設計使用事務指令碼來處理這個流程的。基本上每個環節都對應一
個方法。Buy方法調用依次調用validate,produce,saveorder方法。然後每個方法會在內部用switch和if來判斷是那個產品然後做出相應的處理。很難相信這種代
碼能運行這麼長的時間。由於我們公司產品線變化非常的頻繁。所以基本上每添加新的產品都要修改所有以上方法。由於頻繁的修
改導致了代碼的嚴重可讀性差。每個方法都愈來越長,if語句愈來愈詭異。有些下線的產品代碼其實該清除的。 說了這麼多我覺得
最大的缺陷是組織商務邏輯的方法不合適。我現在被安排維護這些代碼。每改一個新需求,我都心裡發虛啊。怕自己弄錯了if塊。
還好領導們也認為舊的系統維護效率太低了。要求重新設計系統。我覺得應該把商務邏輯使用領域模型來組織。每個行為
不一樣的產品都應該有自己的類。然後對產品建立一個類體系。抽象出每個環節和具體某個產品相關的行為到一個類中。比如
ProductA應該有Validate,GetProduceParameter,等等,這幾個方法。來實現驗證自己,擷取庫存調用介面參數,和擷取訂單相關信
息的方法。這樣buy方法就可以把這些行為委託給具體的產品類。自己就負責流程管理就行了。以後新產品來了,就對新產品建立個
新類。這樣這個業務層也就對修改封閉對擴充開放了。這個沒oo確實很難辦。理想總是很美好的。幾個項目主管和其他同事推崇的
架構方案居然是和petshop一樣的架構。Petshop組織商務邏輯的方式雖說比事務指令碼好了點。但是它的缺點也是很多啊。就我知道
的,這個架構對資料庫表耦合的很緊。基本都是實體類和表一一對應,然後欄位和屬性也一致。網上很多產生實體類的方法也都是
根據資料庫表的中繼資料資訊自動產生的。雖說弄了三層但是那一層也沒逃脫對資料庫結構的依賴。對資料庫結構的變動會導致所有
層的修改。另外 petshop的那個抽象工廠用的也有點多餘把。Ado.net2.0已經實現了這個模式,我們在資料訪問層直接用
DBConnection,DBCommond這些抽象類別就行了。所以我覺得這個petshop純粹是個示範架構和微軟技術的一個花架子。具體到每個不同
的項目,都有自己的項目環境。生搬硬套petshop也是很stupid.說實在的我認為對於petshop那樣的項目需求也根本費不上petshop
那樣的架構。
我心目中一個複雜公司專屬應用程式的架構