元件設計原則之概念篇(四)

2021-06-12 11:10:33 字數 4228 閱讀 3098

穩定抽象原則sap是六個元件設計原則中的最後乙個,它通常與穩定依賴原則sdp結合在一起,用於建立具有較高質量的元件依賴結構。終於是最後乙個了,

穩定抽象原則(the stable-abstractions principle, sap)

a component should be as abstract as it is stable.

元件的抽象程度應該與其穩定程度一致。

sap將元件的穩定性和抽象性聯絡了起來。sap原則規定,乙個穩定的元件應該是抽象的,這樣在具備穩定性的同時也將具備較好的可擴充套件性。此外,它還規定,乙個不穩定的元件應該是具體的,它的不穩定性要求其內部的具體**應該是易於修改的,這種修改不會給其他元件帶來太大的影響。

在乙個相對穩定的元件中,應該包含一些抽象類,這樣就可以對它進行擴充套件。

sap和sdp一起構成了元件的dip(依賴倒轉原則)。sdp要求依賴應該朝著穩定的方向進行,而sap則規定穩定性意味著抽象性,元件的穩定程度要與其抽象程度一致。因此,依賴也應該朝著抽象的方向進行。根據dip,為了降低類與類之間的耦合度,我們要針對介面程式設計,而不要針對實現程式設計,同理,為降低元件之間的耦合度,我們要針對抽象元件程式設計,依賴應該沿著抽象而又穩定的元件來進行。

由於在乙個元件中可以包含多個類,其中有些類是抽象的,而另一些類是具體的,因此在評價乙個元件的抽象程度時,可以通過計算「抽象類的數量佔類總數的百分比」來度量乙個元件的抽象性。

抽象性度量

為了度量元件的抽象性,需引入以下幾個度量指標:

nc(the number of classes):元件中類的總數。

na(the number of abstract classes):元件中抽象類的數目,乙個抽象類中至少包含乙個抽象的方法,抽象類不能被例項化。

a(abstractness):抽象性因子。

a = 0表示元件中沒有任何抽象類;a = 1表示元件中所有的類全部都是抽象類。

我們可以先計算出每乙個元件的抽象性因子a,

結合sap和sdp兩大原則,不難得知,依賴需要沿著穩定的方向進行,也需要沿著抽象的方向進行,可以通過比較乙個依賴鏈上每個元件的a值來判斷依賴鏈是否需要進行調整,a值可以作為乙個改善和調整依賴鏈的指標,但這並不是強制性的。

主序列分析

在bob大叔的asd一書中,有專門的一節來分析穩定性和抽象性之間的關係,並得到了一條主序列(main sequence)。sunny覺得這個過程有點像是在做軟體工程的理論研究,與軟體工程的實踐還是有所區別的,但是,軟體工程的發展既需要理論研究的支援,又需要實踐經驗的驗證,而且了解一下人家如何做研究,本身也是一件挺有意思的事情,接下來我介紹一下bob大叔如何分析元件穩定性和抽象性之間的關係。

為了更好地研究元件的穩定性和抽象性,我們可以引入了乙個二維座標圖,其中抽象性a作為縱軸,不穩定性i作為橫軸,縱軸和橫軸的座標刻度都是從0到1,最穩定、最抽象的元件位於座標左上角(0,1)處,也就是說當不穩定性i=0,抽象性a=1時,元件是最穩定、最抽象的;而那些最不穩定、最具體的元件位於座標的右下角(1,0)處,此時不穩定性i=1而抽象性a=0。理想情況下,我們希望元件都能夠落在這兩個位置附近,也就是說,元件要麼是最穩定最抽象的,要麼是最不穩定最具體的,但是這畢竟只是理想情況,絕大部分元件的抽象性和穩定性都具有一定程度,位於這兩個點之間。

bob大叔認為,在(0,0)附近的元件,是一些具有高度穩定性且具體的元件,但是這種元件僵化程度很高,因為它是具體的,無法對其進行擴充套件,又因為它是高度穩定的,因此很難對它進行更改。簡單來說,位於此處的元件,它會被很多其他元件所依賴(穩定性),但是它很難擴充套件和修改(具體性)。(0,0)附近的區域被稱為痛苦地帶(zone of pain)

在(1,1)附近的元件,也不是乙個好的位置,此處的元件雖然具有最低的穩定性和最高的抽象性,但是由於其穩定性低,因此沒有其他元件依賴它們,即使具有很高的抽象性也不能得到使用。所以這個(1,1)附近的區域被稱為無用地帶(zone of uselessness)

我們希望所設計的元件能夠盡量遠離這兩個區域,而將距離這兩個區域都最遠的軌跡點連線成一條線,這條線就是連線(1,0)和(0,1)點的線,這條線稱為主序列(main sequence),所圖1所示。

圖1 主序列和被排除的區域示意圖

位於主序列上或者靠近主序列的元件都具有一定程度的穩定性和抽象性,雖然元件的理想位置是主序列的兩個端點,但是在實際專案中,大部分元件能夠位於主序列上或者主序列附近就已經很不錯了。

為了更好地度量乙個系統的元件設計是否足夠好,最後再介紹乙個度量:到主序列的距離

到主序列的距離(簡稱距離)是指乙個元件到主序列之間的距離(d),計算公式如下:

該度量值的取值範圍是[0,0.707]。

除此之外,還可以用一種規範化距離(d')來表示,計算公式如下:

d'的取值範圍是[0,1],0表示元件正好位於主序列上,1表示元件到主序列的距離最遠。

通過使用這個度量,我們可以全面分析乙個元件設計方案和主序列之間的一致性。首先可以計算出每個元件的d值,然後對所有d值不在0附近的元件進行複查和調整。這將有助於設計者確定哪些元件更容易維護,哪些元件對變化不敏感、更加穩定。

此外,還可以對元件設計方案進行統計學的分析,例如可以計算出設計中所有元件的d度量值的均值和方差,並且期望得到乙個均值和方差都接近於0,也就是盡量符合主序列的設計。通過方差分析,可以找出一些比較特殊的元件,如圖2所示,在這個分布圖中,大部分元件都沿著主序列分布,但是也有一些元件離主序列較遠,標準偏差z值超過1甚至2,我們需要留意這些偏離較大的元件,盡量找出是什麼原因導致它們非常抽象但具有較少的依賴者,或者非常具體但是有較多的依賴者,必要時我們需要對這些元件進行重構,進一步改進系統的設計。

圖2 元件的d值分布圖(示例)

除此之外,我們還可以繪製每個元件的d'度量值隨時間變化的分布圖,看是否隨著系統版本的公升級或者演化導致某個(或某些)元件的d'值發生了較大的改變,如果在某個版本中乙個元件的d'值發生異常變化或者超過預先設定的乙個閾值,需要找出改變的原因,以便對系統實施更好的重構。

總結

元件設計以及元件之間的依賴關係是有好壞之分的,通過應用這六個元件設計原則,可以在一定程式上改進元件的設計。

重用-發布等價原則(rep):重用的粒度就是發布的粒度。

共同重用原則(crp):乙個元件中的類需一起被重用。如果你重用了元件中的乙個類,那麼就要重用其中所有的類。

共同封閉原則(ccp):乙個元件中的所有類對於同一種型別的變化應該是共同封閉的。乙個變化若對乙個元件產生影響,則將影響該元件中所有的類,而對其他元件不造成影響。

無環依賴原則(adp):在元件的依賴關係圖中不允許存在環。

穩定依賴原則(sdp):朝著穩定的方向進行依賴。

穩定抽象原則(sap):元件的抽象程度應該與其穩定程度一致。

至此,6個元件設計原則全部介紹完畢,雖然有些原則的分析過於理論,看起來也挺枯燥的,但是一旦深入進去發現還是挺有意思的,希望這幾篇文章對大家能夠有所幫助!

架構篇 URI設計原則

author simon 優雅型 羅浮宮 達文西 蒙娜麗莎 中庸型 北京 新聞頻道 新聞id 謝特型 斜槓分隔符 必須用於顯示層次關係正例 反例 使用 提高uri的可讀性正例 禁止在url中使用 目的是提高可讀性,可能被文字檢視器中的下劃線特效遮蔽 反例 禁止使用大寫字母rfc 3986中規定uri...

常用設計原則 精華篇

您的star是我不斷前行的動力 前言 物件導向設計的目標在於支援可維護性復用 一方面需要實現設計方案和源 的復用,另一方面要確保系統易於擴充套件和修改,具有良好的可維護性。一 經常用到的設計原則 使用頻率 單一職責原則 開閉原則 黎克特制代換原則 依賴倒轉原則 介面隔離原則 合成復用原則 一 單一職...

設計原則之開閉原則

定義 乙個軟體實體 類 模組或函式 應當對擴充套件開放,對修改關閉。也就是說軟體實體應盡量在不修改原有 的情況下進行擴充套件。問題 在軟體的生命週期內,因為變化 公升級和維護等原因需要對軟體原有 進行修改時,可能會給舊 中引入錯誤,也可能會使我們不得不對整個功能進行重構,並且需要重新測試。方案 當軟...