摘要:設(shè)計方案的容易改變這就是所謂的軟件構(gòu)建的可維護(hù)性,可擴(kuò)展性和靈活性。這也可能表明類型或方法可能難以維護(hù)?;谠创a中不同運(yùn)算符和操作數(shù)的數(shù)量的合成度量。對修改的封閉這種模塊的源代碼是不可侵犯的。
大綱
軟件維護(hù)和演變
可維護(hù)性度量
模塊化設(shè)計和模塊化原則
OO設(shè)計原則:SOLID
OO設(shè)計原則:GRASP
總結(jié)
什么是軟件維護(hù)?
軟件工程中的軟件維護(hù)是交付后修改軟件產(chǎn)品以糾正故障,提高性能或其他屬性。軟件維護(hù):修復(fù)錯誤,改善性能
在“ISO / IEC 14764:2006軟件工程 - 軟件生命周期過程 - 維護(hù)”
運(yùn)維工程師
維護(hù)是軟件生產(chǎn)中最困難的方面之一,因為維護(hù)包含了所有其他階段的各個方面
用戶報告故障并由維護(hù)工程師處理。
維護(hù)工程師必須具備出色的調(diào)試技能
故障可能存在于產(chǎn)品中的任何地方,故障的原因可能在于現(xiàn)在不存在的規(guī)格或設(shè)計文檔(錯誤/問題本地化)。
需要高超的診斷技能,測試技能和文檔技能(測試,修復(fù)和記錄更改)。
軟件維護(hù)的類型
糾正性維修25%糾錯性
對交付后執(zhí)行的軟件產(chǎn)品進(jìn)行無功修改,以糾正發(fā)現(xiàn)的問題;
適應(yīng)性維護(hù)21%適應(yīng)性
修改交付后執(zhí)行的軟件產(chǎn)品,以保持軟件產(chǎn)品在變化或變化的環(huán)境中可用;
完善性維護(hù)50%完善性
交付后增強(qiáng)軟件產(chǎn)品以提高性能或可維護(hù)性;
預(yù)防性維護(hù)4%預(yù)防性
交付后對軟件產(chǎn)品進(jìn)行修改,以便在軟件產(chǎn)品發(fā)生有效故障前檢測并糾正軟件產(chǎn)品中的潛在故障。
雷曼關(guān)于軟件演化的規(guī)律(Lehman’s Laws on Software Evolution)
反饋系統(tǒng)
持續(xù)變化
持續(xù)增長
質(zhì)量下降
增加復(fù)雜性
自我調(diào)節(jié)
保持組織穩(wěn)定
保持熟悉
軟件維護(hù)和進(jìn)化的目標(biāo)
軟件維護(hù)和演化的目標(biāo):為了提高軟件的適應(yīng)性和適應(yīng)性,并保持其活力,即“長期軟件(低熵軟件)”
提高軟件的適應(yīng)性,延續(xù)軟件生命
Linux內(nèi)核發(fā)展的一個例子:可維護(hù)性指數(shù)
維護(hù)不僅僅是op工程師的任務(wù)......
維護(hù)不僅僅是維護(hù)和操作工程師的任務(wù),也是軟件設(shè)計人員和開發(fā)人員的潛在任務(wù)。 軟件維護(hù)不僅僅是運(yùn)維工程師的工作,而是從設(shè)計和開發(fā)階段就開始了
對他們來說,在設(shè)計和施工階段必須考慮軟件的未來潛在變化/擴(kuò)展;在設(shè)計與開發(fā)階段就要考慮將來的可維護(hù)性
因此,靈活和可擴(kuò)展的設(shè)計/結(jié)構(gòu)被全面考慮,換句話說,“易于改變/擴(kuò)展”。 設(shè)計方案的“容易改變”
這就是所謂的軟件構(gòu)建的“可維護(hù)性”,“可擴(kuò)展性”和“靈活性”。
可維護(hù)性建設(shè)的例子
模塊化設(shè)計與實現(xiàn)模塊化
低耦合和高內(nèi)聚力
OO設(shè)計原則OO設(shè)計原則
SOLID,GRASP
OO設(shè)計模式OO設(shè)計模式
工廠方法模式,Builder模式
橋模式,代理模式
紀(jì)念模式,狀態(tài)模式
基于狀態(tài)的構(gòu)造技術(shù)(自動機(jī)編程)
表驅(qū)動的構(gòu)造技術(shù)
基于語法的構(gòu)造技術(shù)(Grammar-based construction)
許多可維護(hù)性的名字
可維護(hù)性
“軟件系統(tǒng)或組件可輕松修改以糾正故障,改善性能或其他屬性,或適應(yīng)變化的環(huán)境”。
可擴(kuò)展性
軟件設(shè)計/實現(xiàn)將未來的增長考慮在內(nèi),并被視為擴(kuò)展系統(tǒng)能力的系統(tǒng)性測量以及實現(xiàn)擴(kuò)展所需的工作量。
靈活性
軟件根據(jù)用戶需求,外部技術(shù)和社會環(huán)境等容易改變的能力。
可適應(yīng)性
一種交互式系統(tǒng)(自適應(yīng)系統(tǒng))的能力,可以根據(jù)所獲得的有關(guān)其用戶及其環(huán)境的信息,使其行為適應(yīng)個人用戶。
可管理性
如何有效和輕松地監(jiān)控和維護(hù)軟件系統(tǒng),以保持系統(tǒng)的正常運(yùn)行,安全并平穩(wěn)運(yùn)行。
可支持性
基于包含質(zhì)量文檔,診斷信息以及知識豐富且可用的技術(shù)人員的資源,可以有效地使軟件在部署后保持運(yùn)行。
有關(guān)可維護(hù)性的問題
Code review的時候經(jīng)常問的關(guān)于可維護(hù)性的問題:
結(jié)構(gòu)和設(shè)計簡單:改變事物有多容易?
事情緊密或松散(即關(guān)注點分離)?
包/模塊中的所有元素是否具有凝聚力,其職責(zé)是否清晰且密切相關(guān)?
它是否具有過深的繼承層次結(jié)構(gòu),還是贊成繼承的組合?
方法定義中存在多少個獨立的執(zhí)行路徑(即,cycolmatic復(fù)雜度)?
存在多少代碼重復(fù)?
一些常用的可維護(hù)性度量標(biāo)準(zhǔn)
圈復(fù)雜度 - 測量代碼的結(jié)構(gòu)復(fù)雜度。
它是通過計算程序流程中不同代碼路徑的數(shù)量而創(chuàng)建的。
具有復(fù)雜控制流程的程序?qū)⑿枰嗟臏y試來實現(xiàn)良好的代碼覆蓋率,并且將不易維護(hù)。
CC = E-N + 2,CC = P + 1,CC =區(qū)域的數(shù)量
Lines of Code(代碼行數(shù)) - 表示代碼中的近似行數(shù)。
非常高的數(shù)值可能表明某種類型或方法試圖做太多工作,應(yīng)該分手。
這也可能表明類型或方法可能難以維護(hù)。
對于給定的問題,令:
η_1=不同運(yùn)算符的數(shù)目
η_2=不同的操作數(shù)的數(shù)量
Ν_1=運(yùn)算符總數(shù)
Ν_2=操作數(shù)總數(shù)
從這些數(shù)字中可以計算出幾項度量:
程序詞匯表:η=η_1+η_2
程序長度:N=Ν_1+Ν_2
計算的程序長度:N ?=η_1 log_2?〖η_1 〗+η_2 log_2?〖η_2 〗
體積:V=N×log_2?η
難度:D=η_1/2×Ν_2/η_2
代價:E=D×V
難度測量與程序編寫或理解的難度有關(guān)
代價度量使用以下關(guān)系轉(zhuǎn)化為實際編碼時間,
編程所需的時間:T=E/18 秒
Halstead提供的錯誤(B)是對執(zhí)行錯誤數(shù)量的估計。
提供的錯誤數(shù)量:B = E^(2/3)/3000或更接近的B = V/3000也被接受。
Halstead Volume:基于源代碼中(不同)運(yùn)算符和操作數(shù)的數(shù)量的合成度量。
一些常用的可維護(hù)性度量標(biāo)準(zhǔn)
可維護(hù)性指數(shù)(MI)- 計算介于0和100之間的索引值,表示維護(hù)代碼的相對容易性。 高價值意味著更好的可維護(hù)性。 它的計算基于:
Halstead體積(HV)
圈復(fù)雜性(CC)
每個模塊的平均代碼行數(shù)(LOC)
每個模塊注釋行的百分比(COM)。
一些常用的可維護(hù)性度量標(biāo)準(zhǔn)
繼承的層次數(shù)
表示擴(kuò)展到類層次結(jié)構(gòu)的根的類定義的數(shù)量。 等級越深,就越難理解特定方法和字段在何處被定義或重新定義。
類之間的耦合度
通過參數(shù),局部變量,返回類型,方法調(diào)用,泛型或模板實例化,基類,接口實現(xiàn),在外部類型上定義的字段和屬性修飾來測量耦合到唯一類。
良好的軟件設(shè)計決定了類型和方法應(yīng)該具有高內(nèi)聚性和低耦合性。
高耦合表示一種設(shè)計難以重用和維護(hù),因為它與其他類型之間存在許多相互依賴關(guān)系。
單元測試覆蓋率
指示代碼庫的哪些部分被自動化單元測試覆蓋。 (將在第7章中研究)
模塊化設(shè)計和模塊化原則模塊化編程
模塊化編程是一種強(qiáng)調(diào)將程序功能分離為獨立,可互換模塊的設(shè)計技術(shù),每種模塊都包含執(zhí)行所需功能一個方面所需的一切。
將整個程序的代碼高度分解為結(jié)構(gòu)化編程和OOP。
模塊化編程設(shè)計的目標(biāo)是將系統(tǒng)劃分為模塊,并通過以下方式在組件之間分配責(zé)任:
模塊內(nèi)高凝聚力(高內(nèi)聚)
模塊之間的耦合松耦合(低耦合)
模塊化降低了程序員在任何時候都必須處理的總體復(fù)雜性,假設(shè):
將功能分配給將相似功能組合在一起的模塊(分離關(guān)注點)
模塊之間有小而簡單的定義明確的接口(信息隱藏)
內(nèi)聚和耦合的原則可能是評估設(shè)計可維護(hù)性的最重要的設(shè)計原則。
(1)評估模塊性的五個標(biāo)準(zhǔn)
Decomposability(可分解性)
較大的組件是否分解為較小的組件?
Composability(可組合性)
較大的組件是否由較小的組件組成?
Understandability(可理解性)
組件是否可多帶帶理解
Continuity(可持續(xù)性)
規(guī)范的小改動是否會影響本地化和有限數(shù)量的組件?
Protection(出現(xiàn)異常之后的保護(hù))
運(yùn)行時異常的影響是否局限于少數(shù)相關(guān)組件?
(2)模塊化設(shè)計的五條原則
Direct Mapping (直接映射)
Few Interfaces (盡可能少的接口)
Small Interfaces (盡可能小的接口)
Explicit Interfaces (顯式接口)
Information Hiding (信息隱藏)
(3)耦合和內(nèi)聚
耦合
耦合是模塊之間依賴關(guān)系的度量。 如果兩個模塊之間的變化可能需要另一個模塊的變更,則兩個模塊之間存在依賴關(guān)系。
模塊之間的耦合度取決于:
模塊之間的接口數(shù)量(數(shù)量)和
每個接口的復(fù)雜性(由通信類型決定)(質(zhì)量)
HTML,CSS和JavaScript之間的耦合
一個精心設(shè)計的網(wǎng)絡(luò)應(yīng)用程序模塊化:
指定數(shù)據(jù)和語義的HTML文件
規(guī)定HTML數(shù)據(jù)的外觀和格式的CSS規(guī)則
定義頁面行為/交互性的JavaScript
內(nèi)聚
內(nèi)聚是衡量一個模塊的功能或責(zé)任有多強(qiáng)烈程度的一個指標(biāo)。
如果一個模塊的所有元素都朝著相同的目標(biāo)努力,那么它就具有很高的內(nèi)聚。
最好的設(shè)計在模塊內(nèi)具有高內(nèi)聚力(也稱為強(qiáng)內(nèi)聚力)和模塊之間的低耦合(也稱為弱耦合)。
OO設(shè)計原則:SOLIDSOLID:5類設(shè)計原則
(SRP) The Single Responsibility Principle 單一責(zé)任原則
(OCP) The Open-Closed Principle 開放-封閉原則
(LSP) The Liskov Substitution Principle Liskov替換原則
(DIP) The Dependency Inversion Principle 依賴轉(zhuǎn)置原則
(ISP) The Interface Segregation Principle 接口聚合原則
“類改變不應(yīng)該有一個以上的原因”,即一個類應(yīng)該集中精力做一件事,只能一件事。
責(zé)任:“變更的理由”(責(zé)任:變化的原因)
SRP:
類改變不應(yīng)該有一個以上的原因。 (不應(yīng)有多于1個的原因使得一個類發(fā)生變化)
一個類,一個責(zé)任。(一個類,一個責(zé)任)
如果一個類包含了多個責(zé)任,那么將引起不良后果:
引入額外的包,占據(jù)資源
導(dǎo)致頻繁的重新配置,部署等
SRP是原則中最簡單的一種,也是最難做到的一種。(最簡單的原則,卻是最難做好的原則)
(2)開放/封閉原則(OCP)類應(yīng)擴(kuò)展(對擴(kuò)展性的開放)
這意味著模塊的行為可以擴(kuò)展。 我們可以根據(jù)應(yīng)用程序的需求變化,或者為了滿足新應(yīng)用程序的需求,使模塊以新的和不同的方式運(yùn)行。 (模塊的行為應(yīng)是可擴(kuò)展的,從而該模塊可表現(xiàn)出新的行為以滿足需求的變化)
但關(guān)閉修改。(對修改的封閉)
這種模塊的源代碼是不可侵犯的。 沒有人可以對其進(jìn)行源代碼更改。(但模塊自身的代碼是不應(yīng)被修改的)
擴(kuò)展模塊行為的正常方法是對該模塊進(jìn)行更改。(擴(kuò)展模塊行為的一般途徑是修改模塊的內(nèi)部實現(xiàn))
無法更改的模塊通常被認(rèn)為具有固定的行為。(如果一個模塊不能被修改,那么它通常被認(rèn)為是具有固定的行為)
Key:abstraction(關(guān)鍵的解決方案:抽象技術(shù))
“軟件實體(類,模塊,函數(shù)等)應(yīng)該被打開以進(jìn)行擴(kuò)展,但是為了修改而關(guān)閉”,即,使用繼承和組合來改變類的行為
開放封閉原則 - 幾個問題...。
不可能在不修改GraphEditor的情況下添加新的Shape
重要的是要了解GraphEditor添加一個新的形狀
GraphEditor和Shape之間的緊密耦合
不參與GraphEditor就很難測試特定的Shape
If-Else-/Case應(yīng)該被避免
OCP表示單一選擇
只要軟件系統(tǒng)必須支持一組替代方案,系統(tǒng)中的一個且只有一個模塊應(yīng)該知道他們的詳盡列表。
編輯器:一組命令(插入,刪除等)
圖形系統(tǒng):圖形類型集(矩形,圓形等)
編譯器:語言結(jié)構(gòu)集(指令,循環(huán),表達(dá)式等)
“使用指針或?qū)惖囊玫暮瘮?shù)必須能夠使用派生類的對象而不知道它”,即,子類在使用它們的基類時應(yīng)該表現(xiàn)得很好
LSP:子類型必須可替代其基本類型。(子類型必須能夠替換其基類型)
派生類必須可以通過基類接口使用,而不需要客戶端了解其差異。 (派生類必須能夠通過其基類的接口使用,客戶端無需了解二者之間的差異)
在第5-2節(jié)中已經(jīng)討論過可復(fù)用性。
(4)接口隔離原理(ISP)“客戶不應(yīng)該被迫依賴他們不使用的接口”,即保持接口小。
不要強(qiáng)制類來實現(xiàn)它們不能實現(xiàn)的方法(Swing / Java)
不要用很多方法污染界面
避免“胖”的接口
客戶不應(yīng)該被迫依賴他們不使用的方法。(客戶端不應(yīng)依賴于它們不需要的方法)
接口屬于客戶端,而不屬于層次結(jié)構(gòu)。
這個原則處理“胖”接口的缺點。(“胖”接口具有很多缺點)
具有“胖”接口的類是接口不具有內(nèi)聚性的類。(不夠聚合)
該類的接口可以分解為多組成員函數(shù)。(胖接口可分解為多個小的接口)
每個小組服務(wù)一組不同的客戶端(不同的接口向不同的客戶端提供服務(wù))。
因此有些客戶使用一組成員函數(shù),而其他客戶使用其他組。(客戶端只訪問自己所需要的端口)
(5)依賴倒置原理(DIP)高級模塊不應(yīng)該依賴于低級模塊。 兩者都應(yīng)該取決于抽象。
抽象不應(yīng)該依賴于細(xì)節(jié)(抽象的模塊不應(yīng)依賴于具體的模塊)
細(xì)節(jié)應(yīng)該取決于抽象(具體應(yīng)依賴于抽象)
應(yīng)該使用大量的接口和抽象!
為什么DIP?
優(yōu)點:
將類契約正式化。
您根據(jù)前置和后置條件定義例程的服務(wù)。 這非常清楚會發(fā)生什么。
嘗試設(shè)計測試
創(chuàng)建一個測試友好的設(shè)計
測試友好的模塊可能會展現(xiàn)其他重要的設(shè)計特征。
例如:你會避免循環(huán)依賴。 如果您必須從UI多帶帶測試,業(yè)務(wù)邏輯將更好地與UI代碼隔離
OO設(shè)計原則:GRASP什么是GRASP模式
一般責(zé)任分配軟件模式(原則),縮寫為GRASP,包含為OOP中的類和對象分配責(zé)任的準(zhǔn)則。
GRASP模式是幫助理解基本對象設(shè)計的學(xué)習(xí)輔助,并以有條理,合理,可解釋的方式應(yīng)用設(shè)計推理。
這種理解和使用設(shè)計原則的方法是基于對班級分配責(zé)任的模式。
GRASP是關(guān)于如何為“類”和“對象”指派“職責(zé)”的一系列原則
什么是責(zé)任
對象的責(zé)任:與對象的義務(wù)有關(guān)
了解:
了解私有封裝數(shù)據(jù)
了解相關(guān)對象
了解它可以派生或計算的事物
這樣做:
自己做一些事情,比如創(chuàng)建一個對象或者做一個計算
在其他對象中發(fā)起行動
控制和協(xié)調(diào)其他對象的活動。
總結(jié)軟件維護(hù)和演變
可維護(hù)性度量
模塊化設(shè)計和模塊化原則
OO設(shè)計原則:SOLID
OO設(shè)計原則:GRASP
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/71346.html
摘要:大綱什么是軟件復(fù)用如何衡量可復(fù)用性可復(fù)用組件的級別和形態(tài)源代碼級別復(fù)用模塊級別的復(fù)用類抽象類接口庫級別的復(fù)用包系統(tǒng)級別的復(fù)用框架對可復(fù)用性的外部觀察類型變化例行分組實施變更代表獨立分解常見行為總結(jié)什么是軟件復(fù)用軟件復(fù)用軟件復(fù)用是使用現(xiàn)有軟件 大綱 什么是軟件復(fù)用?如何衡量可復(fù)用性?可復(fù)用組件的級別和形態(tài) 源代碼級別復(fù)用 模塊級別的復(fù)用:類/抽象類/接口 庫級別的復(fù)用:API /包 系...
摘要:建模語言建模語言是可用于表達(dá)信息或知識或系統(tǒng)的任何人造語言,該結(jié)構(gòu)由一組一致的規(guī)則定義,目標(biāo)是可視化,推理,驗證和傳達(dá)系統(tǒng)設(shè)計。將這些文件安排到不同的地方稱為源代碼樹。源代碼樹的結(jié)構(gòu)通常反映了軟件的體系結(jié)構(gòu)。 大綱 軟件構(gòu)建的一般過程: 編程/重構(gòu) 審查和靜態(tài)代碼分析 調(diào)試(傾倒和記錄)和測試 動態(tài)代碼分析/分析 軟件構(gòu)建的狹義過程(Build): 構(gòu)建系統(tǒng):組件和過程 構(gòu)建變體...
摘要:軟件評測師教程閱讀持續(xù)更新。。。。單元測試又稱模塊測試,是針對軟件設(shè)計的最小單位程序模塊進(jìn)行正確性檢驗的測試工作其目的在于檢查每個程序單元能否正確實現(xiàn)詳細(xì)設(shè)計說明中的模塊功能性能接口和設(shè)計約束等要求,發(fā)現(xiàn)各模塊內(nèi)部可能存在的各種錯誤。 軟件評測師教程閱讀持續(xù)更新。。。。 目錄大綱閱讀時間完成...
摘要:共性的步驟在抽象類內(nèi)公共實現(xiàn),差異化的步驟在各個子類中實現(xiàn)子類為每個步驟提供不同的實現(xiàn)。模板方法將算法的骨架定義為抽象類,允許其子類提供具體行為。迭代器依次訪問對象的元素而不暴露其基礎(chǔ)表示。 大綱 結(jié)構(gòu)模式 Adapter允許具有不兼容接口的類通過將自己的接口包裝到已有類的接口中來一起工作。 Decorator動態(tài)添加/覆蓋對象的現(xiàn)有方法中的行為。 Facade為大量代碼提供簡化的界...
摘要:遵循特定規(guī)則,利用操作符,終止節(jié)點和其他非終止節(jié)點,構(gòu)造新的字符串非終結(jié)符是表示字符串的樹的內(nèi)部節(jié)點。語法中的生產(chǎn)具有這種形式非終結(jié)符終結(jié),非終結(jié)符和運(yùn)算符的表達(dá)式語法的非終結(jié)點之一被指定為根。 大綱 基于狀態(tài)的構(gòu)建 基于自動機(jī)的編程 設(shè)計模式:Memento提供了將對象恢復(fù)到之前狀態(tài)的功能(撤消)。 設(shè)計模式:狀態(tài)允許對象在其內(nèi)部狀態(tài)改變時改變其行為。 表驅(qū)動結(jié)構(gòu)* 基于語法的構(gòu)...
閱讀 1762·2021-09-22 15:25
閱讀 1319·2019-08-29 12:34
閱讀 1927·2019-08-26 13:57
閱讀 3204·2019-08-26 10:48
閱讀 1457·2019-08-26 10:45
閱讀 806·2019-08-23 18:23
閱讀 748·2019-08-23 18:01
閱讀 1960·2019-08-23 16:07