物件導向參照範例的整體目標是將實作細節封裝起來。因此,關於持續性,我們會想要有一個看起來就像暫時物件的持續性物件。我們應該不需要知道物件會持續存在,或不需要用不同於其他物件的方式來處理它。至少這就是目標所在。
實際上,應用程式有時可能需要控制持續性的各個方面:
-
何時讀取和寫入持續性物件
-
何時刪除持續性物件
-
如何管理交易
-
如何實現鎖定和並行控制
這裡有兩個情況必須考量:物件寫入持續性物件儲存庫的起始時間,以及應用程式要利用物件的變更來更新持續性物件儲存庫的後續時間。
不論任何一種情況,特定機制都會隨著持續性架構所支援的作業而不同。一般而言,這個機制用來將訊息傳給持續性架構,以建立持續性物件。物件持續存在之後,持續性架構很聰明,它會偵測出持續性物件的後續變更,必要時,會將這些變更寫入持續性物件儲存庫中(通常是在確定交易之時)。
以下顯示正在建立的持續性物件範例:
PersistenceMgr 物件是 VBOS 的實例,是一個持續性架構。OrderCoordinator 藉由將 Order 當作 'createPersistentObject' 訊息的引數傳給 PersistenceMgr
來建立持續的 Order。
除非您知道會在某事件序列的特定點上明確儲存物件,否則,通常不需要明確建立這個模型。如果後續作業必須查詢這個物件,物件就必須在資料庫中,因此,必須知道物件會在其中,這一點很重要。
在應用程式將訊息傳送給持續性物件之前,必須先從持續性物件儲存庫中擷取這些物件。請回想一下,在物件導向系統中,是藉由將訊息傳給物件來執行工作。但如果訊息要送往的物件是在資料庫中,而不是在記憶體中,這時會發生問題:您無法將訊息傳給尚不存在的東西!
簡言之,您必須將訊息傳給知道如何查詢資料庫的物件,請擷取正確的物件,建立它的實例。之後,也只有在這時,您才可以傳送原來想傳送的訊息。建立持續性物件實例的物件,有時稱為 Factory 物件。Factory
物件負責建立物件的實例,持續性物件也包括在內。在取得查詢之後,就可以將 Factory 設計成會傳回一組符合查詢的一或多個物件。
一般而言,物件會透過關聯而豐富地連接到其他物件,因此,您通常只需要擷取物件圖中的根物件;透過根物件與其餘項目的關聯,基本上,便會以透通方式從資料庫中「拉出」這些部分。(好的持續性機制在這方面很聰明:它只會在必要之時擷取物件;否則,我們可能會不必要地試著建立大量物件的實例。在仍不需要物件之前擷取物件,是過度簡單的持續性機制所造成的主要效能問題之一。)
下列範例顯示從持續性物件儲存庫中擷取的物件如何建模。在實際的序列圖中,不會顯示 DBMS,因為它應該封裝在 Factory 物件中。
持續性物件的問題就在於它們持續存在! 暫時物件在建立它們的程序結束時便會消失,但持續性物件並不是這樣,它們會持續存在到明確刪除為止。因此,當不再使用持續性物件時,刪除它很重要。
問題是,這很難判斷。原因只在於一個應用程式用完某個物件,並不代表現在和未來的所有應用程式都不再用它。因為物件可能會有它們並不知道的關聯,也確實有這種關聯,有時候就是很難判斷刪除某個物件會不會有問題。
在設計中,這可以利用狀態圖來表達語意:當物件到達結束狀態,便可以說它即將被釋放。之後,負責實作持續性類別的開發人員就可以利用狀態圖資訊呼叫適當的持續性機制行為來釋出物件。使用案例實現化設計者的責任是在適合刪除物件時,呼叫適當的作業,使物件到達它的結束狀態。
如果物件連接許多其他物件,可能很難判斷物件能不能刪除。由於 Factory 物件知道物件的結構,也知道它所連接的物件,因此,要求類別的 Factory
物件負責判斷能不能刪除某個特定實例,通常會很有幫助。持續性架構也可以支援這項功能。
交易會定義一組不可分割的作業呼叫;它們若非全部執行,就是全都不執行。在持續性環境中,交易會定義一組物件的一組變更,這些變更若非全部執行,就是全都不執行。交易會提供一致性,以確保各組物件會從某個一致狀態進入另一個一致狀態。
在使用案例實現化中顯示交易有若干選項:
-
使用文字。您可以利用序列圖邊距中的 Script,依照下圖所示來說明交易界限。這個方法很簡單,可讓您利用任意數量的機制來實作交易。
利用文字註解來呈現交易界限。
-
使用明確訊息。如果所用的交易管理機制利用明確訊息來起始和結束交易,就可以依照下圖所示,在序列圖中明確顯示這些訊息:
顯示啟動和停止交易的明確訊息。
處理錯誤狀況
如果無法執行交易所指定的所有作業(通常是因為發生錯誤),交易就會中止,這時會反向執行交易期間所進行的所有變更。預期的錯誤狀況通常代表使用案例中的例外事件流程。在其他情況下,出現錯誤狀況是因為系統作業失敗。錯誤狀況也應該寫在互動之中。簡單的錯誤和異常狀況可以顯示在它們所出現的交易中;複雜錯誤和異常狀況可能需要它們自己的互動。
特定物件的失敗模式可以顯示在狀態圖中。這些失敗模式的條件式控制處理流程可以顯示在發生錯誤或異常狀況的互動中。
並行用來說明在交易過程中重要系統資源的存取控制。為了使系統保持一致狀態,交易可能需要獨佔性存取系統中的某些重要資源。獨佔性可包括讀取一組物件、寫入一組物件,或讀寫一組物件的能力。
我們來看一下為什麼需要限制存取一組物件的簡單範例。假設我們在執行一個簡單的訂單項目系統。人們打電話進來下訂單,我們再處理訂單,將訂單出貨。我們可以將訂單看成一種交易。
為了說明關於並行控制的需求,比方說,我打電話進來訂購一雙新的登山鞋。當訂單進入系統時,它會檢查庫存中有沒有我需要的登山鞋,大小必須正確。如果有,我們會想預訂這雙靴子,以免在訂單出貨之前被別人買走。在訂單出貨之後,會從庫存中移除這雙靴子。
下單和出貨隔了一段時間,這時靴子是在特殊狀態,它們在庫存中,但它「已確定」給我的訂單。如果我的訂單因故取消(我改變主意,或我的信用卡過期),這雙靴子就會回到庫存中。訂單出貨之後,我們假設我們的小公司不想保留它曾經有靴子的記錄。
並行的目標和交易一樣,是確定系統會從某個一致狀態進入另一個一致狀態中。另外,並行也會致力確保它完成工作所需要的所有資源。並行控制可利用許多不同的方式來實作,其中包括資源鎖定、號誌、共用記憶體鎖和私密工作區。
在物件導向系統中,只是從訊息型樣中,很難得知特定訊息可不可能造成物件的狀態變更。另外,採用不同的實作,某些資源類型可能就不需要存取限制;例如,有些實作會在各項交易開始之時,提供交易本身的系統狀態觀點。在這個情況下,其他程序可能會變更物件的狀態,但不會影響任何其他現有執行中之交易的「觀點」。
為了避免限制實作,在設計之中,我們只想指示交易必須獨佔性存取的資源。我們要用先前的範例來指示我們需要獨佔性存取的已訂購的鞋子。註解所傳送之訊息的說明來指示應用程式需要獨佔性存取物件,便是一個簡單的選擇方案。之後,實作者就可以利用這項資訊來判斷如何最恰當地實作並行需求。以下顯示序列圖範例,圖中有哪些訊息需要獨佔性存取的註解。假設在交易完成時,釋出所有鎖定。
在序列圖中顯示註解的存取控制之範例。
交易所需要的所有物件並非全部都有存取限制,原因在於通常只有少數物件應該有存取限制;限制存取參與交易的所有物件,會浪費珍貴的資源,且會造成效能瓶頸,而不是防止效能瓶頸。
|