《公司專屬應用程式架構模式中文版》學習筆記(轉)

來源:互聯網
上載者:User

標籤:

本書先介紹了一些公司專屬應用程式開發的基礎知識,比如分層架構、WEB表現、商務邏輯、資料庫映射、並發、會話、分布策略等等。通過使用情境、解決方案、UML等手段詳細介紹了設計模式(包括一些常用的設計模式GOF23和本書上新創的設計模式)。瞭解書中這些模式是幹什麼的、它們解決什麼問題、它們是如何解決問題的。這樣,如果你碰到類似的問題,就可以從書中找到相應的模式。可以為你節約成本、縮短項目周期時間、避免風險,以確保項目能夠完美的完成。

 

一、三個基本層次:表現層、領域層、資料來源層

 

層次

職責

表現層

提供服務,顯示資訊(例如在Windows或HTML頁面中,處理使用者請求(滑鼠點擊、鍵盤敲擊等),HTTP請求,命令列調用,批處理API)

領域層

邏輯,系統中真正的核心

資料來源層

與資料庫,訊息系統、交易管理員及其他軟體包通訊

 

關於依賴性的普遍性原則:領域層和資料來源層絕對不要依賴於表現層。

一旦選擇了處理節點,接下來就應該儘可能使所有代碼保持在單一進程內完成(可能是在同一個節點上,也可能拷貝在叢集中的多個節點上)。除非不得已,否則不要把層次放在多個進程中完成。因為那樣做不但損失效能,而且增加複雜性,因為必須增加類似下面的模式,如遠程外觀和資料轉送對象。

複雜性增壓器:分布、顯式多線程、範型差異、多平台開發以及極限效能要求(如每秒100個事務以上)。

 

二、領域邏輯

領域邏輯的組織可以分成三種主要模式:事務指令碼、領域模型、表模組。

三者之間的區別:

事務指令碼是一個過程來控制一系列動作邏輯的執行。

領域模型不再是由一個過程來控制使用者某動作的邏輯,而是由每一個對象都承擔一部分相關邏輯。這些對象可以看成是領域的不同組成部分。

表模組只有一個公用的合約類執行個體,而領域模型對資料庫中每一個合約都有一個相應的合約類的執行個體。

 

 

三、映射到關聯式資料庫

在使用領域模型的時候,它的讀取應該把相關聯的對象也一塊讀出來。例如,讀取一個合約,應該把合約涉及到的產品和定購廠商的對象載入到記憶體中。由時候為了避免這些沒有必要的連帶讀取,我們可以使用【消極式載入】模型。

讀取資料的時候,效能問題可能回變得比較突出。這就導致了幾條經驗法則。

1)、儘可能一次查詢多個記錄,不要一次查詢一個記錄,然後進行多次查詢。可以一次查詢多條相關的記錄,例如使用聯集查詢。或者使用多條SQL語句。

2)避免多次進入資料庫的方法是使用串連(Join),這樣就可以通過一次返回多個表。可以製作一個入口,讓入口完成相關資料的一次性讀取。

3)資料庫中進行最佳化。DBA來最佳化資料庫。

映射到關聯式資料庫的時候,一般會遇到三種情況:

1)  自己選擇資料庫方案。

2)  不得不映射到一個現有資料庫方案,這個方案不能改變。

3)  不得不映射到一個現有資料庫方案,但這個方案是可以考慮改變的。

最簡單的情況是自己選擇資料庫方案,並且不用遷就領域邏輯的複雜性。當已經存在一個資料庫方案的時候,應該逐步建立領域模型並包括資料對應器,把資料儲存到現有的資料庫中。

 

四、並發

並發問題:更新丟失和不一致讀。

並發問題,人們提出了各種不同的解決方案。對於公司專屬應用程式來說,有兩個非常重要的解決方案:一個是隔離,一個是不變性。

隔離是劃分資料,使得每一片資料都可能被一個執行單元訪問。比如檔案鎖。

不變性是識別那些不變的資料,不用總考慮這些資料的並發問題而是廣泛地共用它們。

當有一些可變資料無法隔離的時候,會發生什麼樣的情況呢?總的來說,我們可以使用兩種形式的並發控制策略:開放式並行存取控制和封閉式並行存取控制。

如果把樂觀鎖看作是關於衝突檢測的,那麼悲觀鎖就是關於衝突避免的。

假如Martin和David同時都要編輯Customer檔案。如果使用樂觀鎖策略,他們兩個人都能得到一份檔案的拷貝,並且可以自由編輯檔案。假設David第一個完成了工作,那麼他可以毫無困難地更新他的修改。但是,當Martin想要提交他的修改時,並發控制策略就會開始起作用。原始碼控制系統會檢測到在Martin的修改和David的修改之間存在著衝突,因而拒絕Martin的提交,並由Martin負責指出怎樣處理這種情況。如果使用悲觀鎖策略,只要有人先取出檔案,其他人就不能對該檔案進行編輯。因此,假如是Martin先取出了檔案,那麼David就只能在Martin完成任務並提交之後才能對該檔案進行操作。

 

多種技術處理死結:一種是使用軟體來檢測死結的發生。另一種是給每一個鎖都加上時間限制,一旦到達時間限制,所加的所就會失效,工作就會丟失。

 

軟體事務經常使用ACID的屬性來描述。

原子性(Atomicity):在一個事務裡,動作序列的每一個步驟都必須是要麼全部成功,要麼所有的工作都將復原。部分完成不是一個事務概念。

一致性(Consistency):在事務開始和完成的時候,系統的資源都必須處於一致的、沒有被破壞的狀態。

隔離性(Isolation):一個事務,直到它被成功提交之後,它的結果才對其他所有的事務是可見的。

持久性(Durability):一個已提交事務的任何結果都必須是永久性的,即“在任何崩潰的情況的能儲存下來”。

大多數公司專屬應用程式是在資料庫方面涉及到事務的,但還有很多情況要進行事務控制,比如說哦訊息佇列、印表機和ATM等。為了處理最大的吞吐率,現代的交易處理系統被設計成保證事務儘可能短,儘可能不讓事務跨越多個請求;儘可能晚開啟事務。

 

五、分布策略

按類模型進行分布的方法不可行的主要原因與電腦的基本特點有關。進程內的程序呼叫非常快。兩個對立進程間的程序呼叫就慢了一個數量級。在不同機器間運行過程又要慢一兩個數量級,取決於網路拓撲。

本地介面最好是細粒度介面。但細粒度不能很好地用在遠程調用中。分布對象設計第一定律:不要分布使用對象,大多數情況下是使用叢集系統。

 

六、一些關於具體技術的建議

1、  Java和J2EE

企業級Java Bean(EJB)的價值有多大,這個是JAVA世界中最大的爭論。但是要構建良好的J2EE引用,其實並不需要EJB。使用POJO(普通Java對象)和JDBC同樣能夠完成這一任務。J2EE的設計選擇隨使用的模式不同而不同,同樣,也受到領域邏輯的制約。

2、.NET

.NET、Visual Studio以及微軟世界應用中,其中起決定作用的模式是表模組。.NET大力宣傳Web Services,但是我不會在一個應用程式內部使用Web Services,而只會像Java中一樣,使用它們作為一種允許應用整合的表現層。

2、  預存程序

3、  Web Services

    Web Services使得重用成為現實,並最終導致系統整合商的消失。

4、  其他分層

 

 七、模式

 

領域邏輯模式

1、事務指令碼:使用過程來組織商務邏輯,每個過程處理來自表現層的單個請求。

事務指令碼置於何處將取決於你如何組織你的軟體層次,它可能會位於伺服器頁面、CGI指令碼和分布式會話對象中。我喜歡儘可能的分離事務指令碼。至少應當將它們放在不同的子程式中,而更好的方法則是將它們置於與其他處理表現層和資料來源層的類相獨立的類中。此外,絕不要讓事務指令碼調用任何錶現層邏輯;這樣會使我們容易修改代碼和測試事務指令碼。

可以用兩種方法來把事務指令碼組織成類。一種是把多個事務指令碼放在一個類中,每個類圍繞一個主題將相關的事務指令碼組織在一起。另一種方法則是每個事務指令碼對應一個類,通過命令模式來完成訊息傳遞。

2、領域模型:合并了行為和資料的領域的對象模式。

領域模型按照它的複雜程度分,可以分為:簡單領域模型和複雜領域模型。簡單的領域模型如【活動記錄】,可以應對領域邏輯比較簡單的系統。複雜的領域邏輯需要複雜的領域模型。

3、表模組:處理某一資料庫表或視圖中所有行為的商務邏輯的一個執行個體。

表模組以一個類對應資料庫中的一個表來組織領域邏輯,而且使用單一的類執行個體來包含將對資料進行的各種操作程式。它與領域邏輯的主要區別在於,如果你有許多訂單,領域模型對每一個訂單都有一個對象,而表模組則只用一個對象來處理所有的訂單。

4、服務層:通過一個服務層來定義應用程式邊界,在服務層中建立一組可用的操作集合,並在每個操作內部協調應用程式的響應。

 

 

資料來源架構模式

1、表資料入口:充當資料庫表訪問入口的對象。一個執行個體處理表中所有的行。

表資料入口包含了用於單個表或視圖的所有SQL,如選擇、插入、更新、刪除等。其他代碼調用它的方法來實現所有與資料庫的互動。

2、行資料入口:充當資料來源中單條記錄入口的對象,每行一個執行個體。

3、活動記錄:一個對象,它封裝資料庫表或視圖中某一行,封裝資料庫訪問,並在這些資料上增加了領域邏輯。

4、資料對應器:在保持對象和資料庫彼此獨立的情況下在二者之間移動資料的一個映射器層。

資料對應器是分離記憶體對象與資料庫的一個軟體層。其職責是在記憶體對象與資料庫之間的傳遞資料並保持它們彼此獨立。有了資料對應器,記憶體對象甚至不需知道資料庫的存在;它們也不需要SQL介面代碼,當然也不需要知道資料庫方案。由於資料對應器是映射器的一種形式,因此資料對應器自身根本不為領域層所察覺。

 

對象—關係行為模式

1、工作單元:維護受業務影響的對象列表,並協調變化的寫入和並發問題的解決。

工作單元是一個記錄這些變化的對象。只要開始做一些可能會對資料庫有影響的操作,就建立一個工作單元去記錄這些變化。每當建立、改變或者刪除一個對象時,就通知此工作單元。

工作單元的關鍵是在提交的時候,它決定要做什麼。它開啟一個事務,做所有的並發檢查(使用悲觀離線鎖和樂觀離線鎖)並向資料庫寫入所做的修改。開發人員根本不用顯式調用資料庫更新方法。這樣,他們就不必記錄所修改的內容或者不必擔心的參考完整性如何影響他們的操作順序。

2、標識映射:通過在映射中儲存每個已經載入的對象,確保每個對象只載入一次。當要訪問對象的時候,通過映射來尋找他們。

3、消極式載入:一個對象,它雖然不包含所需要的所有資料,但是知道怎麼擷取這些資料。

實現消極式載入的四種方法:延遲初始化、虛代理、值保持器、重影。

 

對象—關係結構模式

1、標識域:為了在記憶體對象和資料庫行之間維護標識而在對象記憶體的一個資料庫標識域。

資料庫中通過主鍵來區分資料行,然而,記憶體對象不需要這樣一個鍵,因此為對象系統能夠保證正確的身份確認(在C++中是直接用原始記憶體位置)。

2、外鍵映射:把對象間的關聯映射到表間的外鍵引用。

3、關聯表映射:把關聯儲存為一個表,帶有指向(有關聯所串連的)表的外鍵。

4、依賴映射:讓一個類的部分類執行資料庫映射。

5、嵌入值:把一個對象映射成另一個對象表的若干欄位。

6、序列化LOB:通過將多個對象序列化到一個大對象(LOB)中儲存一個對象圖,並儲存在一個資料庫欄位中。

7、單表繼承:將類的繼承層次表示為一個單表,表中的各列代表不同類中的所有域。

8、類表繼承:用每個類對應一個表來表示類的繼承層次。

9、具體表繼承:用每個具體類對應一個表來表示類的繼承層次。

 

對象—關係中繼資料映射模式

1、中繼資料映射:在中繼資料中保持關係—對象映射的詳細資料。

中繼資料映射使開發人員可以以一種簡單的表格形式來定義映射,這些映射可由通用代碼來處理,從而實現讀取、插入和更新資料的細節。使用中繼資料映射最主要的決策是如何根據運行代碼來表示中繼資料中的資訊。有兩種主要的途徑:代碼產生和反射編程。

2、查詢對象:描述一次資料庫查詢的對象。

3、資產庫:協調領域和資料對應層,利用類似於集合的介面來訪問領域對象。

 

WEB表現模式

1、模型—視圖—控制器(MVC):把使用者介面互動分到不同的三種角色中。

2、頁面控制器:在WEB網站上為特定頁面或者動作處理請求的對象。

 

 

3、前端控制器:為一個WEB網站處理所有請求的控制器。

4、模板視圖:通過在HTML也面中嵌入標記向HTML發送訊息。

5、轉換視圖:一個視圖,它一項一項地處理領域資料,並且把它們轉換成HTML。

 

 

6、兩步視圖:用兩個步驟來把領域資料轉換成HTML。第一步,形成某種邏輯頁面;第二步,把這些邏輯頁面轉換成HTML頁面。

7、應用控制器:一個用來處理螢幕導航和應用程式流程的集中控制點。

 

分布模式

1、遠程外觀:為細粒度對象提供粗粒度的外觀來改進網路上的效率。

2、資料轉送對象:一個為了減少方法調用次數而在進程間傳輸資料的對象。

資料序列化

 

離線併發模式

1、樂觀離線鎖:通過衝突檢測和交易回復來防止並發業務事務中的衝突。

2、悲觀離線鎖:每次只允許一個業務事務訪問資料以防止並發業務事務中的衝突。

3、廣泛鎖定:用一個鎖鎖住一組相關的對象。

4、隱含鎖:允許架構或層超類型代碼來擷取離線鎖。

 

工作階段狀態模式

包括客戶工作階段狀態、伺服器工作階段狀態、資料庫工作階段狀態。

通常使用資料轉送對象來傳輸資料。資料轉送對象可以在網路上序列化,因此,即使是很複雜的資料也可以傳輸。

客戶工作階段狀態:將工作階段狀態保持在用戶端。客戶工作階段狀態有一定的優點。特別是支援無狀態服務器對象,從而提高最大的叢集效能和容錯恢複。當然,如果客戶崩潰了,它所有的會話資料就丟失了,但使用者通常認為這合乎情理。對於安全問題,就要對傳輸的資料進行加密。

客戶資料轉送:客戶也需要儲存資料。大客戶的應用可以用自己的資料結構來儲存。如果使用HTML,情況就複雜一些。一般有三種方法:URL參數、表單的隱藏欄位和Cookie。

 

伺服器工作階段狀態:將工作階段狀態以序列化形式存放在伺服器端。

伺服器會話裡面最簡單的一種方法是把會話資料放在應用伺服器的記憶體中。可以將會話資料以會話標識號作為鍵標識存放在記憶體映射表中。只需要客戶給出會話標識號,伺服器就可以從映射表中取出會話資料。這種方法假設應用伺服器有足夠的記憶體處理,而且是只能有一個應用伺服器,沒有叢集——如果這個應用伺服器崩潰了,所有的會話資料就丟失得無影無蹤。

解決方案是將伺服器工作階段狀態序列化存放到資料庫中,用一個以會話標識號為索引值的表,表中需要有一個序列化LOB存放序列化後的工作階段狀態。還要對作廢的會話進行處理,尤其在一個面向顧客的應用中。一種方法是用一個監督進程檢查並刪除到期的會話,但這樣會造成很多與會話表的串連。Kai Yu提供了他使用的一個好方法:將會話表分成12段,每兩個小時輪換一次,輪換時先刪除時間最舊的段中所有的資料,並把所有新的資料放到該段中。雖然這樣會把那些超過24個小時的會話強制移除,但實際上不用去擔心這樣極少數的情況。

實現舉例:

Java實現       最常用的伺服器工作階段狀態技術是使用HTTP會話或者使用有狀態會話bean。

HTTP會話是讓WEB伺服器儲存工作階段狀態的一種簡單方法。

使用有狀態會話bean,它需要一個EJB伺服器。EJB容器負責持久和鈍化處理,因此很容易實現。

。NET實現   伺服器工作階段狀態可以很容易地使用內建的工作階段狀態功能實現。預設情況下,.NET將工作階段狀態放在伺服器處理序內。也可以換成通過狀態服務存取,可以在本地也可以在遠程。如果使用遠端狀態服務,可以在重啟WEB伺服器後依然使用原來的會話資料。通過在設定檔中指定是使用進程內方式還是使用狀態服務,因此不必要修改應用程式。

 

資料庫工作階段狀態是將會話資料作為已提交的資料儲存到資料庫中。

 

基本模式

1、  入口:一個封裝外部或資源訪問的對象。

實際上這是一個十分簡單的封裝器模式。封裝外部資源,建立一個簡單的API,並用入口將對該API的調用轉移到外部資源上。

2、  映射器:在兩個獨立的對象之間建立通訊的對象。

映射器通常需要在層與層之間進行資料交換。這種資料交換一旦被啟用,工作方式就是顯而易見的。映射器的使用痛點在於如何啟用,因此你無法在被映射子系統中的任何一方直接調用它。有時可以使用一個第三方的子系統來完成映射並調用映射器。另一個可選的方案是讓映射器成為某個子系統的觀察者。通過監視子系統中發生的事件,映射器就可以調用了。

3、層超類型:某一類型充當一層中所有類型的超類型。

某一層中所有的對象都具有某些方法,但你並不希望這些方法在系統內被多次複製而產生冗餘代碼。此時你可以將這些行為移到一個通用的層超類型中。

4、分離介面

在一個包中定義介面,而在另一個與這個包分離的包中實現這個介面。

 

 

5、  註冊表

一個眾所周知的對象,其他對象可以通過該對象找到公用的對象和服務。

6、  值對象:一個如貨幣或日期範圍這樣的小而簡單的對象,判斷時並不根據標識ID。

在由多種類型對象組成的對象中,區分引用對象和值對象是有用的。二者之中值對象通常規模小一些;它類似於許多非純粹物件導向程式設計語言中的原始類型。通常來說,我們傾向於認為值對象是小對象,如貨幣對象或日期對象;而引用對象是大的對象,如訂單或顧客。

7、  貨幣:表示一個貨幣值

物件導向的程式設計使你可以通過建立一個處理貨幣的貨幣類來解決貨幣與金額(小數點)這類問題。令人感到奇怪的是,居然沒有任何主流的類庫提供這個類。

建立一個貨幣類,在其中儲存金額和幣種,可以以整數或定點小數的方式來儲存金額。

8、  特殊情況:針對特殊情況提供特殊行為的子類。

9、  外掛程式:在配置時而非編譯時間的串連類。

10、服務樁:在測試時移除對有問題服務的依賴。

企業級系統通常要依賴於第三方服務(例如信用評分、稅率查詢和價格引擎)的訪問。有這類系統開發經驗的開發人員都知道:如果依賴於完全不受自己控制的外部資源,通常會使軟體項目受挫。第三方服務的特性是不可預知的,而且這些服務通常是遠端,因而軟體效能和可靠性也會受到損害。

這種依賴關係可能會導致測試無法進行,從而使得開發週期成倍增長。在測試時,用運行在本地的、快速的、位於記憶體中的服務樁來代替服務將會改善你的開發經驗。

當你發現對某一特定服務的依賴妨礙你的開發與測試時,就應當使用服務樁。許多XP的實踐者使用術語“類比對象”來代替服務樁。
11、記錄集:表格式資料在記憶體中的表現方式。
    

記錄集模式的思想是通過一個記憶體中資料結構來提供解決這一問題的完整方案,該資料結構看起來與SQL查詢的結果極為類似,但是它可以由系統中其他組件來產生和操控。

記錄集通常無需你親自建立,而是由所有軟體平台的銷售商提供。ADO.NET中的data set和JDBC2.0中的row set都是記錄集的例子。

目前有一種記憶體資料庫sqlite,讀取存取速度很快,有興趣的可以研究,是開源的。

 

http://blog.csdn.net/byxdaz/article/details/4811772

 

《公司專屬應用程式架構模式中文版》學習筆記(轉)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.