作者:admin 時間:2022-08-04
本文為《軟件可靠性簡介》培訓課程中摘錄的公開內容。在原公眾號“永恒之地”后臺回復“軟件可靠性”,可下載完整版培訓課件。
本文目錄:
一、理解兩個概念:耦合和內聚
二、避錯設計
三、查錯設計
四、容錯設計
一、理解兩個概念:耦合和內聚
講軟件可靠性設計之前,我們先理解兩個概念,一個叫耦合,一個叫內聚,在文章中會用到。
耦合是對一個軟件結構內不同模塊之間互連程度的度量。耦合強弱取決于模塊間接口復雜程度,進入或訪問一個模塊的點,以及通過接口的數據。
低耦合:
如果兩個模塊中的每一個都能獨立地工作而不需要另一個模塊的存在,那么它們彼此獨立,這意味著模塊間無任何連接,耦合程度最低。但是,在一個軟件系統中不可能所有模塊之間都連接。
如果兩個模塊彼此間通過參數交換信息,而且交換的信息僅僅是數據,那么這種耦合稱為數據耦合。
中耦合:
如果傳遞的信息中有控制信息(盡管有時這種控制信息以數據形式出現),則這種耦合稱為控制耦合。
高耦合:
一個模塊訪問另一個模塊的內部數據;
一個模塊不通過正常入口而轉到另一個模塊的內部;
兩個模塊有一部分程序代碼重疊;
一個模塊有多個入口(這意味著一個模塊有幾種功能)。
兩個模塊都既往公共環境送數據又從里面取數據,叫公用耦合,這種耦合比較緊密,介于數據耦合和控制耦合之間。
一個模塊與另一個模塊的內部屬性有關,不經調用直接使用另一個模塊的程序代碼或內部數據,那么這兩個模塊之間就存在內容耦合。
內容耦合是最高程度的耦合,應該避免使用。
內聚標志著一個模塊內各個元素彼此結合的緊密程度,它是信息隱藏和局部化概念的自然拓展。簡單地說,理想內聚的模塊只做一件事情。內聚按模塊內各個元素彼此結合的緊密程度通常分為高內聚、中內聚和低內聚3類。設計時應該力求做到高內聚。
高內聚:
如果一個模塊內的處理元素和同一個功能密切相關,而且這些處理順序執行(通常一個處理元素的輸出數據作為下一個處理元素的輸入數據),則成為順序內聚。
如果模塊內所有處理元素屬于一個整體,完成一個單一的功能,則稱為功能內聚。功能內聚是最高程度的內聚。
中內聚:
如果一個模塊內的處理元素是相關的,而且以特定次序執行,則稱為過程內聚。
如果模塊中所有元素都使用同一個輸入或產生同一個輸出數據,則稱為通信內聚。
低內聚:
如果一個模塊完成一組任務,這些任務彼此間即使有關系,關系也是很松散的,就叫做偶然內聚。
如果一個模塊完成的任務在邏輯上屬于相同或相似的一類(例如,一個模塊產生各種類型的全部輸出),稱為邏輯內聚。
如果一個模塊包含的任務在同一段時間內執行(例如,模塊完成各種初始化工作),就叫時間內聚。
二、避錯設計
軟件可靠性設計方法很多。《可靠性工程師手冊》一書中主要介紹了三種方法:避錯、查錯、容錯設計。
預防為主,是軟件可靠性設計的首要方法。
我們在講可靠性設計時提到,可靠性定量設計需要大量的基礎數據,這在實際中非常困難的。定性方法是在產品設計和開發中制定和實施產品可靠性設計準則,這是提高設計開發產品可靠性最有效的方法。
軟件可靠性也一樣,減少出錯,就要遵守一些準則?!犊煽啃怨こ處熓謨浴芬粫?,避錯設計一共提了三大塊,分別是考慮可靠性的設計準則,啟發規則,以及正確的編程風格。
(1)考慮可靠性的軟件設計準則
1.模塊化,指的是我們可以將復雜問題分解為若干易于處理的子問題;過程、函數、子程序和宏,都可作為模塊。
2.模塊獨立,則是要求每一個模塊完成一個相對獨立的特定子功能。
3.信息隱蔽,是說一個模塊內包含的信息(過程和數據)對于不需要這些信息的模塊來說,是不能訪問的。
4.局部化,使得一些關系密切的軟件元素物理上彼此靠近,例如在一些模塊中使用局部數據元素。
(2)啟發規則
軟件開發的實踐積累了很多經驗,總結這些經驗可以得出許多啟發規則,幫助軟件工程師改進軟件的設計,提高軟件的可靠性。常用的啟發規則:
1.提高模塊獨立性,力求實現高內聚低耦合。
2.控制模塊規模,模塊的實現語句不宜過多,通常不超過60行。
3.控制軟件的深度、寬度、扇入、扇出。這里我解釋一下這些概念:
4.模塊的作用域應在控制域之內。模塊的作用域是指受該模塊內一個判定條件影響的所有模塊范圍。模塊的控制域是指該模塊本身以及所有該模塊的下屬模塊(包括該模塊可以直接調用的下級模塊和可以間接調用的更下層的模塊)。
我以一個具體例子解釋下:
如圖所示,模塊C的控制域為模塊C、E和F;若在模塊C中存在一個對模塊D、E和F均有影響的判定條件,即模塊C的作用域為模塊C、D、E和F(圖中帶陰影的模塊),則顯然模塊C的作用域超出了其控制域。
由于模塊D在模塊C的作用域中,因此模塊C對模塊D的控制信息必然要通過上級模塊B進行傳遞,這樣不但會增加模塊間的耦合性,而且會給模塊的維護和修改帶來麻煩(若要修改模塊C,可能會對不在它控制域中的模塊D造成影響)。
因此,軟件設計時應使各個模塊的作用域處于其控制域范圍之內。
本例中的可改進方法:
①將判定位置上移。如將模塊C中的判定條件上移到上級模塊B中或將模塊C整個合并到模塊B中。
②將超出作用域的模塊下移。如將模塊D移至模塊C的下一層上,使模塊D處于模塊C的控制域中。
5.降低模塊接口的復雜度。接口信息傳遞簡單,且和模塊功能一致。
6.設計單入口和單出口的模塊。不要使模塊間出現內容耦合,模塊的入口、出口只有一個。
(3)正確的編碼風格。
這個很好理解,簡單講就是要代碼簡明、清晰、易讀、易懂;有正確、完整的文檔等。
三、查錯設計
避錯設計雖然可以大幅度降低引入的錯誤或缺陷,但不太可能避免缺陷的發生,因此,查錯設計就非常重要。查錯設計分為主動式查錯和被動式查錯兩種。
主動式查錯,顧名思義,是主動進行對程序狀態的檢查。
舉例如下:
●例1:提供服務器定期監控功能,查看定位CPU高耗線程,提示系統管理員關注。
●例2:提供服務端軟件心跳監測功能,實時監控服務器的運行狀態。
被動式查錯,在程序不同位置設置監測點等待錯誤征兆的出現,從而查出缺陷。
舉例如下:
●例1:在各單元/模塊處理業務邏輯前,應首先判斷所有輸入參數、條件的合法性。
1.進行條件判斷。
2.使用斷言。斷言是一個在假設不正確時會預警的函數或宏指令,可使用斷言監錯在開發階段,斷言可以提示相互矛盾的假設、傳入程序的不良數值等等。在維護階段,斷言可以表明改動是否影響到了程序其它部分。
3.對異常情況進行處理。
●例2:對于等待信號的程序,應設置等待次數或時間的上限,避免潛在的死循環。
●例3:對于冗余的輸入數據應執行一致性驗證。
四、容錯設計
容錯的含義:在發生故障的情況下,系統不失效,仍然能夠正常工作的特性。軟件的容錯設計與硬件的冗余設計為相似。
容錯軟件:
在程度上,對自身故障具有屏蔽能力
在程度上,能從錯誤狀態自動恢復到正常狀態
因缺陷而發生故障時,仍然能夠在程度上完成預期的功能
軟件設計為什么要容錯?原因如下:
◆沒有保證軟件無缺陷的方法,開發低缺陷率軟件的成本通常會非常高,有時接受帶有缺陷的軟件可能更為經濟。
◆即使系統看起來很可靠,也需要容錯
例如規格說明可能存在缺陷,驗證和確認活動可能不正確。
◆在關鍵情形下,軟件系統容錯
有高可用需求,系統失效代價很高時,要容錯。
接下來介紹《可靠性工程師手冊》一書中提到的兩種基本的容錯設計方法,N-版本程序設計方法和恢復塊法。
N-版本程序設計方法
對于一個給定的功能,由N個(N≥2)個不同的設計組獨立編制出N個不同的程序,然后在N臺機器上運行并比較結果。如果N個版本運行的結果一致,則認為結果正確。若不一致,則按照表決原則,判定結果的正確性。
書本上也是很枯燥的文字,大家可能不好理解,下面這個示意圖則很直觀的把這個方法表示出來:
◆不同的小組用許多變體(不同的設計方法,不同的算法,不同的程序設計語言,不同的編譯程序,不同的實現技術,不同的設計師及程序員)實現相同的規格說明,所有變體同時進行計算,利用表決系統選擇多數作為輸出。
◆假定不同的小組犯相同錯誤的概率低。
◆是最常用方法,例如:在許多型號空中客車商用飛機中,用這種方法去保證。
N-版本程序設計方法,類似于硬件設計里的硬件冗余,即并聯模型。
恢復塊法
在每次模塊處理結束時都要檢驗運行結果,一旦發現異常后,通過替代模塊再次運行。
我們用示意圖表達如下:
◆相同的規格說明被實現成若干個明確不同的版本,順序執行
◆利用驗收檢測程序選擇接受的輸出
◆強制每個版本使用不同的算法,以降低相同錯誤的概率
◆驗收檢測程序的設計困難,獨立于所使用的計算
◆由于冗余版本是依次順序執行的,用于實時系統時應注意
恢復塊法,類似于具有轉換開關的硬件冗余,即旁聯模型。
版權所有© 國可工軟科技有限公司 滬ICP備2020030271號