設計機制是從相對應的分析機制中提煉的成果(另請參閱概念:分析機制)。設計機制對概念分析機制添加具體的詳細資料,但尚未涉及特定技術 - 例如,特定廠商在物件導向 DBMS
方面的實作方式。如同分析機制一樣,設計機制也可能引用一或多種型樣,也就是所謂的架構 或設計型樣。
同樣地,實作機制是利用特定的程式語言及其他實作技術(例如,特定廠商的中介軟體產品),進一步修飾相對應的設計機制。一個實作機制可能引用一或多個慣用語或實作型樣。
以持續性的分析機制為例:
-
許多個 (2,000) 小型物件(每一個是 200 位元組)可能只需要保留幾秒鐘,不必保存。
-
幾個大型物件可能需要儲存在磁碟上長達數個月之久,且永不更新,但需要用到複雜的擷取方法。
這些物件需要各種不同的持續性支援;持續性支援的設計機制中可能有下列特性:
-
內建記憶體儲存裝置;特性:總計最大 1 Mb(大小 x 數量);讀取、寫入、更新最快。
-
快閃卡;特性:最大 8 Mb;更新和寫入慢;讀取速度適中。
-
二進位檔;特性:100 Kb 至 200 Mb;更新慢;讀取和寫入慢。
-
資料庫管理系統 (DBMS);特性:100 Kb 以上(基本上沒有上限);更新、讀取及寫入最慢。
請注意,以上評定為「慢」的速度是相對於內建記憶體儲存裝置的速度。很顯然,在某些環境中,利用快取可以明顯改善存取時間。
最初,設計機制與實作機制的對映可能不盡理想,但至少可讓專案開始運作、識別尚未察覺的風險,以及展開進一步的調查與評估。隨著專案持續進行及情況益趨明朗,就需要修正對映。
採取「由上而下」和「由下而上」的方法,反覆修正設計機制與實作機制的對映,剔除多餘的路徑。
由上而下。採取「由上而下」的方法時,透過必要的分析機制,新的和修正的使用案例實現化會在必要的設計機制上產生新的需求。這些新的需求可能發現設計機制的其他特性,迫使機制必須分割。系統的複雜性和效能之間也需要折衷:
-
太多不同的設計機制會讓系統更複雜。
-
太少的設計機制會誇大特性值的合理範圍,導致某些實作機制發生效能問題。
由下而上。採取「由下而上」的方法時,經過調查可用的實作機制之後,可能會找到一次可滿足多種設計機制的產品,但也會迫使設計機制必須進行某些調適或重新劃分。您一定希望將實作機制的數量減到最少,但太少也會導致效能問題。
決定使用 DBMS 來儲存類別 A 的物件之後,您可能會試著以此儲存系統中的所有物件。但這已證實非常無效率,或非常難以處理。並不是所有需要持續性的物件都一定要儲存在 DBMS
中。有些物件可能持續存在,但可能只有此應用程式才經常存取,其他應用程式卻很少存取。從 DBMS 讀取物件再放入記憶體中並定期同步化,這種混合式策略可能才是最佳之道。
範例
航班可以儲存在記憶體中快速存取,儲存在 DBMS 中長期保存;但這樣又需要一套將兩者同步化的機制。
一個用戶端類別以多種設計機制來折衷處理不同的特性,這種情形也很普遍。
由於實作機制通常以現成元件的套件形式呈現(作業系統和中介軟體產品),因此,必須根據成本、規格矛盾或樣式一致性,進行某種程度的最佳化。另外,機制通常相互依存,導致難以清楚地將服務劃分到設計機制。
範例
-
通知機制可以根據跨流程通訊機制。
-
錯誤報告機制可以根據持續性機制。
整個詳述階段會不斷地修飾,且最後一定是下列兩者之間的折衷方案:
-
在期望的特性上,完全「符合」設計機制的用戶端需求。
-
為了取得和整合太多不同的實作機制而引發的成本和複雜性。
整體目標一定是追求一套簡單又乾淨俐落的機制,能夠滿足大型系統的概念整合性、簡化性及簡潔性。
持續性設計機制可以對映至實作機制,如下所示:
分析機制與設計機制之間可能的對映關係。虛線箭頭表示「由...特殊化」,意指設計機制的特性繼承自分析機制,但會進一步特殊化和修正。
完成機制最佳化之後會出現下列對映:
以機制之間的對映來表示用戶端類別的設計決策;Flight 類別需要兩種持續性:以現成檔案庫常式實作的內建記憶體儲存裝置,以現成 ObjectStorage 產品實作的資料庫。
必須可雙向對映,以利於變更實作機制時輕易分辨用戶端類別。
工作成果:專案特定準則中記載設計機制及相關使用細節。工作成果:軟體架構文件說明從分析機制、設計機制到實作機制之間的關係(或對映),也提及這些選項的相關理論。
如同分析機制一樣,設計機制也可以透過協同作業來塑造,這可能實例化一或多個架構型樣或設計型樣。
範例:持續性機制
本範例援引一個從 JDBC™(Java 資料庫連線功能)繪製的 RDBMS
持續性型樣。雖然在這裡只顯示設計,但 JDBC 已提供一些類別的實際程式碼,所以這裡的描述已經很接近實作機制。
「靜態觀點:JDBC」圖顯示協同作業中的類別(嚴格來說是分類器角色)。
靜態觀點:JDBC
黃色的類別代表已提供的類別,其他(myDBClass 等)則是由設計師連結來建立機制。
在 JDBC 中,用戶端使用 DBClass 來讀取和寫入持續資料。DBClass 負責透過 DriverManager 類別來存取 JDBC 資料庫。開啟資料庫連線 (Connection)
之後,DBClass 就可以建立 SQL 陳述式來傳送至底層的 RDBMS,並透過 Statement 類別來執行。Statement 類別負責與資料庫「交談」。SQL 查詢的結果會傳回到 ResultSet
物件中。
DBClass 類別負責讓另一個類別實例持續存在。它瞭解 OO 與 RDBMS 的對映,並提供與 RDBMS 溝通的行為。DBClass 會壓縮物件、將物件寫入 RDBMS、從 RDBMS
讀取物件資料,以及建置物件。每一個持續性類別各有一個相對應的 DBClass。
PersistentClassList 會傳回一組持續性物件做為資料庫查詢(例如,DBClass.read())的結果。
接下來我們提出一連串動態觀點來說明此機制的實際運作情形。
JDBC:起始設定
必須先起始設定之後,才能存取任何持續性類別。
若要起始設定資料庫連線,DBClass 必須呼叫 DriverManager getConnection() 操作,並提供 URL、使用者及密碼,以載入適當的驅動程式。
getConnection() 操作會嘗試對給定的資料庫 URL 建立連線。DriverManager 會嘗試從一組已登錄的 JDBC 驅動程式中選擇適當的驅動程式。
參數:
url:jdbc:subprotocol:subname 格式的資料庫 URL。此 URL 用來尋找實際的資料庫伺服器,在此與 Web 無關。
user:資料庫使用者,亦即代表此使用者建立連線
pass:使用者的密碼
傳回:
URL 的連線。
JDBC:建立
為了建立新的類別,持續性用戶端會要求 DBClass 建立新的類別。DBClass 會以預設值建立新的 PersistentClass 實例。DBClass 會以 Connection 類別的 createStatement()
操作來建立新的 Statement。接著會執行 Statement,並將資料插入資料庫中。
JDBC:讀取
為了讀取持續性類別,持續性用戶端會要求 DBClass 讀取。DBClass 會以 Connection 類別的 createStatement() 操作來建立新的 Statement。接著會執行 Statement,且資料會傳回到
ResultSet 物件中。然後,DBClass 會建立新的 PersistentClass 實例,並填入已擷取的資料。資料會傳回到資料收集物件中,此為 PersistentClassList 類別的實例。
附註:傳入 executeQuery() 的字串和傳入 read() 的字串不一定要完全相同。DBClass 會利用傳入 read() 的準則來建置 SQL 查詢,從資料庫擷取持續資料。這是因為我們希望 DBClass
的用戶端不須瞭解資料庫內部的技術,也一樣可以建立有效的查詢。此技術已封裝在 DBClass 內。
JDBC:更新
為了更新類別,持續性用戶端會要求 DBClass 更新。DBClass 會從給定的 PersistentClass 物件擷取資料,並以 Connection 類別的 createStatement() 操作來建立新的
Statement。建置 Statement 之後就會執行更新,並以類別提供的新資料來更新資料庫。
重點:負責將 PersistentClass「壓縮」並寫入資料庫的是 DBClass。這也就是為何在建立 SQL 陳述式之前必須從給定的 PersistentClass 中擷取的原因。
附註:在上述機制中,PersistentClass 必須為所有持續資料提供存取常式,供 DBClass 用來存取資料。但這樣就允許外部存取原本私有的特定持續屬性。為了從封裝資料的類別中取出持續性資料,這是必須付出的代價。
JDBC:刪除
為了刪除類別,持續性用戶端會要求 DBClass 刪除 PersistentClass。DBClass 會以 Connection 類別的 createStatement() 操作來建立新的 Statement。接著會執行
Statement,並從資料庫中移除資料。
在實作此設計的過程中,必須在 DBClass 至持續性類別的對映上做一些決策,例如,每一個持續性類別各有一個 DBClass,並分配到適當的套件。這些套件將依賴提供的 java.sql(請參閱 JDBC™ API
文件)套件,其中包含 DriverManager、Connection、Statement 及 ResultSet 這些支援類別。
|