原文地址:http://www.uml.org.cn/zjjs/201309043.asp
架構設計則為滿足架構需求的質量屬性尋找適當的戰術。對如何實現特定的質量屬性感興趣。質量需求指定了軟體的響應,以實現業務目標。我們感興趣的是設計使用設計模式、架構模式或架構策略建立設計的“戰術”。
是什麼使一個設計具有了可移植性,一個設計具有了高效能,而另一個設計具備了可整合性?實現這些質量屬性依賴於基本的設計策略。我們將對這些稱之為“戰術”的設計決策進行分析。戰術就是影響質量屬性響應控制的設計決策。戰術集合稱為“架構策略”。架構模式以某種方式將戰術打包在一起。
系統設計是由決策集合組成。對設計師來說,每個戰術都是一個設計選擇。例如,其中一個戰術引入了冗餘,以提高系統的可用性。這是提高可用性的一個選擇但是不是唯一選擇。
我們將每個系統質量屬性的戰術組織為層次形式,但是每個層次只是為了說明一些戰術,而且任何戰術列表都肯定是不完成的。
1. 可用性戰術
恢復和修復是可用性的重要方面,為了阻止錯誤發展成故障,至少能夠把錯誤限制在一定的範圍內,從而使修復成為可能。維持可用性的所有方法包括某種型別的冗餘,用來檢測故障的某種型別的健康監視,以及當檢測到故障時某種型別的恢復。有些情況下,監視或恢復是自動進行的,有時需要手動。
我們事項考慮錯誤檢測,然後分析錯誤恢復,最後討論錯誤預防。
1> 錯誤檢測
用於識別錯誤的3個戰術是命令/響應、心跳和異常
⑴命令/響應。一個元件發出一個命令,並希望在預定義的時間內收到一個來自審查元件的響應。可以把該戰術用在共同負責某項任務的一組元件內。客戶機也可以使用這種戰術,以確保伺服器物件和到伺服器的通訊路徑在期望的效能邊界內操作。可以用一種層級形式組織“命令/響應”錯誤探測器,其中最底層的探測器對與其共享一個處理器的軟體程式發出命令,較高層的錯誤探測器對較低層的探測器發出命令。與所有程式發出命令的遠端錯誤探測器相比,這種戰術所使用的通訊頻寬更少。
⑵心跳。一個元件定期發出一個心跳訊息,另一個元件接收聽該資訊。如果心跳失敗,則假定最初的元件失敗,並通知錯誤糾正元件。心跳還可以傳遞資料。例如,自動櫃員機定期向伺服器傳送一次交易日誌。該訊息不僅起到心跳的作用,而且傳送了要處理的資料。
⑶異常。識別錯誤的一個方法就是遇到了異常。
命令/響應和心跳戰術在不同的程式中操作,異常戰術在一個程式中操作。異常處理程式通常將錯誤在語義上轉換為可以被處理的形式。
2> 錯誤恢復
錯誤恢復由準備恢復和修復系統兩部分組成。
⑴表決。執行在冗餘處理器上的每個程式都具有相同的輸入,它們計算髮送給表決者的一個簡單的輸出值。如果表決者檢測到單處理器的異常行為,那麼就中止這一行為。表決演算法可以是“多數規則”或“首選元件“或其他演算法。該方法用於糾正演算法的錯誤操作或者處理器的故障,通常用在控制系統。每個冗餘元件的軟體可以由不同的小組開發,並且在不同平臺上執行。稍微好一點情況是在不同平臺上開發一個軟體元件,但是這樣的開發和維護費用非常昂貴。
⑵主動冗餘(熱重啟)。所有的冗餘元件都以並行的方式對事件做出響應。因此他們都處在相同的狀態。僅使用一個元件的響應,丟棄其他元件的響應。錯誤發生時,使用該戰術的系統停機時間通常是幾毫秒,因為備份是最新的,所以恢復所需要的時間就是切換時間。
⑶被動冗餘(暖重啟/雙冗餘/三冗餘)
一個元件(主要的)對事件做出響應,並通知其他元件(備用的)必須進行狀態更新。當錯誤發生時,在繼續提供服務前,系統必須首先確保備用狀態是最新的。該方法也用在控制系統中,通常情況是在輸入資訊通過通訊通道或感測器到來時,如果出現故障必須從主元件切換到備用元件時使用。
⑷備件
備用件是計算平臺配置用於更換各種不同的故障元件。出現故障時,必須將其重新啟動為適當的軟體配置,並對其狀態進行初始化。定期設定持久裝置的系統狀態的檢查點,並記錄持久裝置的所有狀態變化能夠使備件設定為適當的狀態。這通常用作備用客戶機工作站,出現故障時,使用者可以離開。該戰術的停機時間通常是幾分鐘。
⑸Shadow操作。以前出現故障的元件可以在短時間內以“shadow模式”執行,以確保在恢復該元件前,模仿工作元件行為。
⑹狀態再同步。主動和被動冗餘戰術要求恢復的元件在重新提供服務前更新其狀態。更新的方法取決於可以承受的停機時間、更新的規模以及更新所要求的訊息的數量。
⑺檢查點/回滾。檢查點就是記錄所建立的一致狀態,或者是定期進行,或者是對具體事件做出響應。有時系統會以一種不同尋常的方式出現故障,可檢測到其狀態不一致。在這種情況下,應該使用上一個一致狀態檢查點和拍了快照後所發生的事務日誌來恢復系統。
3> 錯誤預防
⑴從服務中刪除。該戰術從操作中刪除了系統的一個元件,以執行某些活動來防止預期發生的故障。一個示例就是重新啟動元件,以防止記憶體洩露導致故障的發生。如果從服務中刪除是自動的,則可以設計架構策略來支援它。如果是人工進行的,則必須對系統進行設計以對其提供支援。
⑵事務。事務就是繫結幾個有序的步驟,以能夠立刻撤銷整個繫結。如果程式中的一個步驟失敗的話,可以使用事務來防止任何資料受到影響,還可以使用事務來防止訪問相同資料的幾個同時執行緒之間發生衝突。
⑶程式監視器。一旦檢測到程式中存在著錯誤,監視程式就可以刪除非執行進行,併為該程式建立一個新的例項,就像在備件戰術中一樣,初始化為某個適當的狀態。
總結了上面討論的戰術。
2. 可修改性戰術
可修改戰術的目標是控制實現、測試和部署變更的時間和成本。把可修改性戰術根據其目標進行分組。一組可修改性戰術目標是減少由某個變更直接影響的數量。這組稱為“區域性化修改”。另一組可修改戰術的目標是限制對區域性化的模組的修改。這組稱為“防止連鎖反應”。兩組之間的差別是有直接受變更影響的模組(那些調整其責任來完成變更的模組)間接受變更影響的模組(那些責任保持不變,但必須改變其實現來適應直接受影響的模組)。第三組戰術的目標是控制部署時間和成本。我們把這組戰術叫做“延遲繫結時間”。
1> 區域性化修改。
目標是在設計期間為模組分配責任,以把預期的變更限制在一定範圍內。其戰術有:維持語義的一致性、預期期望的變更、泛化該模組、限制可能的選擇。
⑴維持語義的一致性。語義的一致性是在模組中責任之間的關係。目標是確保所有這些責任都能夠協同工作,不需要過多地依賴其他模組。該目標是通過選擇具有語義一致性的責任來實現的。耦合和內聚指標是度量語義一致性的嘗試,但它們遺漏了變更的上下文。相反根據一組預期的變更來度量語義一致性。其中一個子戰術就是“抽象通用服務”。通過專門的模組提供通用服務通常被視為支援重用。但是抽象通用服務也支援可修改性。如果已經抽象出了通用服務,那麼對這些通用服務的修改只需要進行一次,而不需要在使用這些服務的每個模組中都進行修改。此外,對使用這些服務的模組的修改不會影響到其他使用者。不僅支援區域性化修改,而且還能夠防止連鎖反應。抽象通用服務的示例就是應用框架的使用和其他中介軟體軟體的使用。
⑵預期期望的變更。考慮所預想的變更的集合提供了一個評估特定的責任分配的方法。基本的問題是“對於每次變更,所建議的分解是否限定了為完成變更所需要修改的模組的集合?”一個相關的問題是“根本不同的變更會影響相同模組嗎?”這與語義一致性有什麼不同呢?根據語義一致性分配責任,假定期望的變更在語義上是一致的。預測期望變更的戰術不關心模組責任的一致性,它所關心的是使變更的影響最小。在實際中很難單獨使用該戰術,因為不可能預期所有變更。基於此原因,我們通常結合語義一致性來使用該戰術。
⑶泛化該模組。使一個模組更通用能夠使它根據輸入計算更廣泛的功能。可以該輸入看作是為該模組定義了一種語言,這可能會如同使常數成為輸入引數一樣簡單;也可能如同把該模組實現為解釋程式,並使輸入引數成為解釋程式的語言中的程式一樣複雜。模組越通用,越有可能通過調整語言而非修改模組來進行請求變更。
⑷限制可能的選擇。修改(尤其是在產品線中的修改)的範圍可能非常大,因此可能會影響很多模組。限制可能的選擇將會降低這些修改所造成的影響。例如,產品線的某個變化點可能允許處理器的變化。將處理器變更限制為相同家族的成員就限制了可能的選擇。
2> 防止連鎖反應。
修改所產生的一個連鎖反應就是需要改變該修改並沒有直接影響到的模組。例如,改變了模組A以完成某個特定的修改,那麼必須改變模組B,這僅僅是因為改變了A,在某種意義上來說,是因為它依賴於模組A。
確定的8中型別的依賴。
① 語法。
1.資料。要使B正確編譯或執行,由A產生並由B使用的資料型別或格式必須與B所假定的資料的型別或格式一致。
2.服務。要使B正確編譯和執行,由A提供並且由B呼叫的服務的簽名必須與B的假定一致。
② 語義。
1.資料。要使B正確執行,由A產生並由B使用的資料語義必須與B所假定的資料的語義一致。
2.服務。要使B正確執行,由A提供並且由B呼叫的服務的語義必須與B的假定一致。
③ 順序。
1.資料。要使B正確執行,它必須以一個固定的順序接收由A產生的資料。
2.控制。要使B正確執行,A必須在一定的時間限制內執行。
④ A的一個介面身份。A可以有多個介面。要使B正確編譯和執行,該介面的身份(名稱或控制程式碼)必須與B的假定一致。
⑤ A的位置(執行時)。要是B正確執行,A執行的位置必須與B的假定一致。
⑥ A提供的服務/資料的質量。要是B正確執行,設計A所提供的資料或服務的質量的一些屬性必須與B的假定一致。例如,某個特定的感測器所提供的資料必須有一定的準確性,以使B的演算法能夠正常執行。
⑦ A的存在。要是B正常執行,A必須存在。例如,如果B請求物件A提供服務,而A不存在並且不能動態建立,那麼B就不能正常執行。
⑧ A的資源行為。要使B正常執行,A的資源行為必須與B的假定一致。這可以是A的資源使用(A使用與B相同的記憶體)或資源擁有(B保留了A認為屬於它的資源)。
沒有任何一個戰術一定能夠防止語義變更的連鎖反應。首先討論與特定模組的介面相關的那些戰術——資訊隱藏和維持現有的介面——然後討論一個違反了依賴鏈的戰術——仲裁者的使用。
⑴資訊隱藏。資訊隱藏就是把某個實體(一個系統或系統的某個分解)的責任分解為更小的部分,並選擇使哪些資訊成為公有的,哪些資訊成為私有的。可以通過指定的介面獲得公有責任。資訊隱藏的目的是將變更隔離在一個模組內,防止變更擴散到其他模組。這是防止變更擴散的最早的技術。它與“預期期望的變更有很大關係”,因為它使用那些變更作為分解的基礎。
⑵維持現有的介面。如果B依賴於A的一個介面的名字和簽名,則維持該介面及其語法能夠使B保持不變。當然如果B對A有語義依賴性,那麼該戰術不一定會起作用,因為很難遮蔽對資料和服務的含義的改變。此外,也很難遮蔽對服務質量、數量質量、資源使用和資源擁有的依賴性。還可以通過將介面與實現分離來實現該介面的穩定性。這使得能夠建立遮蔽變化的抽象介面。變化可以包含在現有的責任中,或者可以通過用模組的一個實現代替另一個實現來包含變化。
實現該戰術的模式包括:
1.新增介面。大多數程式語言允許多個介面。可以通過新介面提供最新的可見的服務或者資料,從而使得現有的介面保持不變並提供相同的簽名。
2.新增介面卡。給A新增一個介面卡,該介面卡把A包裝起來,並提供原始A的簽名。
3.提供一個佔位程式A。如果修改要求刪除A,且B僅依賴於A的簽名,那麼為A提供一個佔位程式能夠使B保持不變。
⑶限制通訊路徑。限制與一個給定的模組共享資料的模組。也就是說,減少使用由該給定模組所產生的資料的模組的數量,以及產生由該模組所使用的資料的模組的數量。這會減少連鎖反應,因為資料產生/使用引入了導致連鎖反應的依賴。
⑷仲裁者的使用。如果B對A具有非語義的任何型別的依賴,那麼,在A和B之間插入一個仲裁者是有可能的,以管理與該依賴相關的活動。所有這些仲裁者都有不同的名字,但我們將根據列舉的依賴型別對每個仲裁者進行討論。如前所述,在最糟糕的情況下,仲裁者不能補償語義變化。仲裁者是:
1.資料(語法)。儲存庫充當資料的生產者和使用者之前的仲裁者。儲存庫可以把A產生的語法轉換為符合B的語法。一些釋出/訂閱模式(那些具有通過中央元件的資料流的模式)也可以把該語法轉換為符合B的語法。MVC和PAC模式把一種形式的資料(輸入輸出裝置)轉換為另一種形式的資料(由MVC和PAC中的抽象所使用的形式)。
2.服務(語法)。正面、橋、調停者、策略、代理和工廠模式都提供了把服務的語法從一種形式轉換為另一種形式的仲裁者。因此,可以使用他們防止A的變化擴散到B。
1. A的介面的身份。可以使用經紀人模式遮蔽一個介面的身份中的變化。如果B依賴於A的一個介面的身份並且該身份發生了變化,通過向經紀人新增該身份,並使該經紀人與A的新身份進行連線,B可以保持不變。
2. A的位置(執行時)。名稱伺服器能夠使A的位置發生變化,且不影響B。A負責在名稱伺服器中註冊其當前的位置,B從名稱伺服器中檢索該位置。
3. A的資源行為或由A控制的資源(執行時)。資源管理器是一個負責進行資源非配的仲裁者。某些資源管理器(例如那些基於實時系統中速率單調性分析的管理器)可以保證滿足在某些限制條件中的所有請求。當然,A必須把對該資源的控制轉讓給資源管理器。
4. A的存在。工廠模式能夠根據需要建立例項,因此B對A的存在的依賴性由該工廠的操作來滿足。
3>推遲繫結時間。
可修改性場景包括通過減少需要修改的的數量不能滿足的兩個元素—部署時間以及允許非開發人員進行修改。推遲繫結時間支援這兩個場景,但需要提供額外的基礎結構來支援後期繫結。
可以把各個時間決策繫結到執行系統中。我們討論一下那些影響部署時間的決策。系統的部署由某個過程來規定。當修改由開發人員進行時,通常會有一個測試和分佈過程,該過程確定進行改變和該改變對終端使用者可用之間的時間延遲。在執行時繫結意味著系統已經為該繫結做好了準備,並且完成了所有的測試和分配步驟。推遲繫結時間還能夠使終端使用者或系統管理員進行設定,或提供影響行為的輸入。
許多戰術的目的是在載入時或執行時產生的影響,如下所示:
1. 執行時註冊支援即插即用操作,但需要管理註冊額外開銷。例如,釋出/訂閱註冊可以在執行時或載入時實現。
2.配置檔案的目的是在啟動時設定引數。
3. 多型允許方法呼叫的後期繫結。
4.元件更換允許載入時間繫結。
5.遵守已定義的協議允許獨立程式的執行時繫結。
3. 效能戰術
效能戰術的目標就是對在一定的時間限制內到達系統的事件生成一個響應。事件到達後系統或者對該事件進行處理,或者由於某些原因處理被阻塞。下面是產生響應時間的兩個基本因素:資源消耗和閉鎖時間
資源消耗:包括CPU、資料儲存、網路通訊頻寬和記憶體,但它也可以包括由設計中的特定系統所定義的實體。例如必須對緩衝器進行管理,並且對關鍵部分的訪問必須是按順序進行的。事件可以是各種型別的,每種型別的事件都經過了一個處理序列。
閉鎖時間:可能會由於資源爭用、資源不可用或者計算依賴於另外一個還不能得到的計算結果而導致計算不能使用某個資源,從而阻止了計算的進行。
1.資源爭用。這些事件可能是單個流,也可能是多個流。爭用同一個資源的多個流或相同流中爭用同一個資源的不同事件會增加等待時間。
2.資源的可用性。即使沒有爭用,如果資源不可用,計算也無法進行下去。資源離線、元件故障、或其他原因都會導致資源不可用。在任何情況下,設計師都必須確定資源不可用可能會導致急劇增加等待時間的位置。
3.對其他計算的依賴性。計算可能必須等待,因為它必須與一個計算的結果同步,或者是因為它在等待它所啟動的一個計算的結果。例如,它可能會從兩個不同的源讀取資訊,如果這兩個源是按順序讀取的話,等待時間將會比並行讀取高。
1> 資源需求。
事件流是資源需求的源。需求的兩個特徵是:資源流中的事件之間的時間(在事件流中多長時間進行一次請求);每個請求所消耗的資源是多少。
減少等待時間的一個戰術就是減少處理一個事件流所需要的資源。方法如下:
1. 提高計算效率。處理事件或訊息中的一個步驟就是應用某個演算法。改進在關鍵的地方所使用的演算法將減少等待時間。有時可以用一種資源換取另一種資源。例如,可以把仲裁者資料儲存在儲存庫中,也可以重新生成,這取決於時間和空間資源的可用性。該戰術通常用在處理器上,但用在其他資源上也是有效的,如磁碟。
2. 減少計算開銷。如果沒有資源請求,就可以減少處理需求。
減少等待時間的另外一個戰術就是減少所處理事件的數量。可以用一下方式進行:
1.管理事件率。如果可以降低監視環境變數處的取樣頻率,就可以減少需求。如果系統進行了超量設計的話,這樣做是不可行的,其他時候使用不必要的高取樣率來建立多個流之間的和諧週期。也就說,某個流或事件被過取樣,以使他們可以被同步化。
2.控制取樣頻率。如果沒有對外部生成的事件的到達進行控制,則可以用一個較低的頻率對排隊的請求進行取樣,這樣可能會導致請求的丟失。
用於減少或管理需求的其他戰術包括控制資源的使用。
3.限制執行時間。限制用多少執行時間對事件做出響應。有時這樣做有意義,有時沒有意義。對於迭代、依賴於資料的演算法,限制迭代的數量就是限制執行時間的一個方法。
4.限制佇列的大小。這控制了排成佇列到達事件的最大數量,因此控制了用來處理到達事件的資源。
2> 資源管理
儘管不能控制對資源的需求,但對這些資源的管理會影響響應時間。下面是一些資源管理的戰術。
1.引入併發。如果可以並行處理,就可以減少閉鎖時間。可以通過在不同的執行緒上處理不同的事件流或者建立額外的執行緒來處理不同的活動集來引入併發。引入併發後,適當地把執行緒分配給資源(負載均衡)非常重要,以儘可能利用併發。
2.維持資料或計算的多個副本。客戶機—伺服器模式中的客戶機是計算的副本。使用副本的目的是減少在中央伺服器上進行所有的計算時出現的爭用。快取記憶體的資料通常是現有資料的一個副本,因此使用副本一致和同步就變成了系統必須承擔的責任。
3.增加可用資源。速度更快的處理器、額外的處理器、額外的記憶體以及速度更快的網路都可以減少等待時間。在選擇資源時,通常會考慮成本,但增加資源絕對也是一個減少等待時間的戰術。
3> 資源仲裁
當存在資源爭用時,必須對資源進行排程。我們需要對處理器、緩衝器和網路進行排程安排。設計師的目標是理解每個資源使用的特性,並選擇之一致的排程策略。
從概念上講排程策略都有兩部分:優先順序分配和分派。所有的排程策略都分配優先順序。一些常見的排程策略為:
1.先進先出。FIFO佇列同等看待對資源的所有請求,並依次對其進行處理。在FIFO佇列中,一個請求可能被另一個需要很長時間來生成響應的請求阻止。只有所有請求優先順序都是相同的,這就不是一個問題;但如果一些請求的優先順序高於其他請求的優先順序,就存在這個問題。
--固定優先順序排程。
固定優先順序排程為每個請求資源的源分配一個特定的優先順序,並按該優先順序順序分配資源。該策略能夠保證為優先順序較高的請求提供更好的服務,但是,對一些優先順序較低的請求來說,肯能要等待很長的時間才能得到服務,因為它前面有很多優先順序較高的請求。3個常見的優先順序策略為:
⑴語義重要性。每個流都根據生成它的任務的某個與領域特性被靜態地分配一個優先順序。這種排程在大型機系統中,其中領域特性是任務啟動的時間。
⑵時限時間單調。時限時間單調是一種靜態優先順序分配,它將較高的優先順序分配給具有較短時限時間的流。在排程的不同優先順序流具有實時時限時間時,使用該排程策略。
⑶速率單調。速率單調是週期流的一種靜態優先順序分配,它將較高的優先順序分配給具有較短週期的流。該排程策略是時限時間單調的一種特殊情況,但它更為我們所熟知,作業系統對此提供支援的可能性較大。
--動態優先順序排程
⑴輪轉。輪轉是一種排程策略,它對請求進行排序,然後在允許的時候,把資源分配給該排序中的下一個請求。輪轉的一個特殊形式就是迴圈執行,在迴圈執行中,資源分配是每隔一個固定的時間進行的。
⑵時限時間最早優先。時限時間最早優先根據具有最早的視線時間的掛起請求來分配優先順序。
--靜態排程。迴圈執行排程是一種排程策略,在該策略中,離線確定先佔點和資源分配順序。
4. 安全性戰術
安全性戰術分為:與抵抗攻擊有關的戰術、與檢測攻擊有關的戰術以及從攻擊中恢復有關的戰術。給門裝鎖就是在抵抗攻擊,在房子中放一個運動感測器就是在檢測攻擊,給房子上保險就是從攻擊總恢復。
1> 抵抗攻擊。
我們把認可、機密性、完整性和保證確定為目標。可以組合使用下面的戰術來實現這些目標。
1.對使用者身份驗證。身份驗證能夠保證進行訪問的使用者或遠端計算機確實是它所聲稱的使用者或計算機。密碼、一次性密碼、數字證書以及生物識別均提供身份驗證。
2.對使用者進行授權。授權能夠保證經過了身份驗證的使用者有權訪問和修改資料或服務。這通常通過在系統中提供一些訪問控制模式進行管理。可以對單個使用者進行訪問控制,也可以對某一類使用者進行訪問控制。也可以根據使用者分組、使用者角色或個人列表定義使用者類。
3.維護資料的機密性。應該對資料進行保護,以防止未經授權的訪問。一般通過對資料和通訊鏈路進行某種形式的加密來實現機密性。另一方面,通訊鏈路一般不具有授權控制,對於通過公共可訪問的通訊鏈路傳資料來說,加密是唯一的保護措施。對基於web的鏈路,可以通過VPN或者SSL來實現該鏈路。
4.維護完整性。應該如期提供資料,資料中可能有冗餘資訊、如校驗或雜湊值,他們可以與原始資料一起進行加密,也可以單獨加密。
5.限制暴露的資訊。攻擊者通常會利用暴露的某個弱點來攻擊主機上的所有資料和服務。設計師可以設計服務在主機上的分配,以使只能在每個主機上獲得有限的服務。
6.限制訪問。防火牆根據訊息源或目的地埠來限制訪問。來自未知源的訊息可能是某種形式的攻擊。限制對已知源的訪問並不總是可行的,例如,一個公共網站上可能會有來自未知源的請求。這種情況中使用一個配置就是所謂的解除管制區。
2> 檢測攻擊。
檢測攻擊通常通過“入侵檢測”系統進行。
3> 從攻擊中恢復。
可以把從攻擊中恢復的戰術分為恢復狀態相關的戰術和與識別攻擊者相關的戰術。在將系統或資料恢復到正確狀態時所使用的戰術與用於可用性的戰術發生了重疊,因此他們都是從不一致的狀態恢復到一致狀態。差別就是要特別注意維護系統管理資料的冗餘副本,如密碼、訪問控制列表、域名服務和使用者資料資料。
用於識別攻擊者的戰術就是“維持審計追蹤”。審計追蹤就是應用到系統中的資料的所有事務和識別資訊的一個副本。可以使用審計資訊開追蹤攻擊者的操作。支援認可並支援系統恢復。
5. 可測試性戰術
可測試性戰術目標是允許在完成一個軟體開發的增量後,輕鬆地對軟體進行測試。我們對兩類用於測試的戰術進行討論:提供輸入並捕獲輸出;內部監視。
1> 輸入/輸出
1.記錄回放。記錄回放是指捕獲跨介面的資訊,並將其作為測試專用軟體的輸入。在正常操作中操作中跨一個介面的資訊儲存在某個儲存庫中,它代表來自一個元件的輸出和傳到一個元件的輸入。記錄該資訊使得能夠生成對其中一個元件的測試輸入,並儲存用於以後比較測試輸出。
2.將介面與實現分離。將介面與實現分離允許實現的代替,以支援各種測試目的。佔位實現允許在缺少被佔用的元件時,對系統的剩餘部分進行測試。用一個元件代替某個專門的元件能夠使被代替的元件充當系統剩餘部分的測試工具。
3.特化訪問路線/介面。具有特化的測試介面允許通過測試工具並獨立於其正常操作,來捕獲或指定元件的變數值。例如,可以通過允許特化的介面提供原資料,測試工具利用該介面推動其活動。
2> 內部監視
內建監視器。元件可以維持狀態、效能負載、容量、安全性或其他可通過介面訪問的資訊。此介面可以是該元件的一個永久介面,也可以是通過instrumentation技巧臨時引入的介面,如面向方面程式設計或預處理程式巨集。一個常見的技巧就是當監視狀態被啟用時記錄事件。監視狀態實際上會增加測試工作,因為隨著監視的關閉,可能必須重複測試。儘管額外測試需要一定的開銷,但這卻使元件活動的可見性得以提高,這樣做是值得的。
6. 易用性戰術
易用性與使用者完成期望任務的難易程度以及系統為使用者提供的支援種類有關。有兩種型別的戰術支援易用性,每種戰術所針對的是兩種類別的“使用者”。第一類是執行時,包括那些在系統執行期間支援使用者的戰術。第二類基於使用者介面設計的迭代特性,它在設計時支援介面開發人員。
1> 執行時戰術。
一旦系統執行,就可以通過為使用者提供關於系統正在做什麼的反饋,以及用於提供發出基於易用性命令的能力來增強易用性。例如,在糾錯或更高效的操作中,“取消”、“撤銷”、“聚合”和“顯示多個檢視”均為使用者提供支援。
1.維持任務的一個模型。這種情況下,所維持的模型是關於任務的資訊。任務模型用於確定上下文,以使該系統瞭解使用者試圖做什麼,並提供各種協助。例如,知道句子通常以大寫字母開頭能夠使應用程式糾正該位置的小寫字母。
2.維持使用者的一個模型。維持的模型是關於使用者的資訊。它確定了使用者對該系統的瞭解,使用者在期望的響應時間方面的行為,以及特定於某個使用者或某類使用者的其他方面。例如,維持使用者模型能夠使系統以使用者可以閱讀月面的速度滾動頁面。
3.維持系統的一個模型。所維持的模型就是關於系統的資訊。它確定了期望的系統行為,以便為使用者提供適當的反饋。系統模型反饋預測了諸如完成當前活動所需要時間的專案。
2> 設計時戰術。
在測試過程中,通常會頻繁修改使用者介面。也就是說,易用性工程師將為開發人員提供對當前介面設計的修改,開發人員將實現這些修改。這導致了對語義一致的可修改性的求精。
將使用者介面與應用的其餘部分分離開來。區域性化所期望的變更是語義一致的一個基本原理。因為在開發中和部署後,我們預計使用者介面頻繁發生變化,因此單獨維護使用者介面程式碼將會變更區域性化在某個地方。開發用於實現該戰術並支援使用者介面修改的軟體架構模式為:
模型——檢視——控制器
表示——抽象——控制
Seeheim
Arch/Slinky
7. 戰術與架構模式的關係
Active Objcet設計模式將方法執行從方法呼叫中分離出來,以增強併發,並簡化對駐留在其自身控制執行緒中的物件的同步訪問。
該模式由6個元素組成:代理,它提供了允許客戶對主動物件呼叫公共訪問方法的介面;方法請求,它定義了用於執行主動物件的方法的一個介面;啟用介面,它維持了掛起方法請求的一個緩衝器;排程程式,它決定接下來執行什麼方法請求;附屬,他定義可建模為主動物件的行為和狀態;將來,它允許客戶獲得方法呼叫的結果。
該模式的動機就是增強併發性——這是一個效能目標。因此其主要目的就是實現“引入併發“效能戰術。然而,還要注意該模式包含的其他戰術。
資訊隱藏(可修改性)。每個元素都選擇了它將實現的責任,並將其實現隱藏在介面後面。
仲裁者(可修改性)。該代理充當著把變化緩衝到方法呼叫中的仲裁者。
繫結時間(可修改性)。主動物件模式假定對該物件的請求在執行時到達該物件。然而,並沒有確定客戶機與代理的繫結時間。
排程策略(效能)。排程程式實現一些排程策略。
對設計師來說,分析過程包括理解嵌入在實現中的所有戰術;設計過程包括在關於哪些戰術最和將實現系統期望的目標方面,做出一個明智的選擇。
8. 架構模式和樣式
軟體中架構模式與建築物中的架構樣式類似,它由幾個將他們組合起來以維持架構完整性的關鍵特性和規則組成。架構模式由以下幾個因素確定:
一組元素型別(如資料儲存庫或計算數學函式的元件)
指出其相互關係的元素的拓撲佈局。
一組語義限制(如管道——過濾器樣式中的過濾器是純資料轉化器——他們以增量形式將其輸入流轉換為輸出流,但並不控制上游流或下游元素)。
一組互動機制(如子例程呼叫、事件——調閱者、黑板)、他們確定元素將如何通過允許的拓撲進行協調。
架構模式和戰術之間是什麼關係呢?正如已經說明的那樣,我們把戰術看作是設計的基本“構建塊”,並根據該戰術建立架構模式和策略。