❶ vscode怎麼計算代碼度量值
vscode代碼度量值計算方法指南,助力高效前端開發想知道如何使用vscode計算代碼度量值嗎?vscode作為流行的前端開發工具,提供了一系列實用功能,其中包括代碼度量值計算。本文將由php小編魚仔深入講解vscode計算代碼度量值的方法,包括具體步驟和技巧。了解這些知識將幫助您優化代碼質量,提升開發效率。
操作方法:
1、雙擊進入軟體,點擊點擊上方菜單欄中的"分析"。
2、接著點擊下方選項列表中的"計算代碼度量值"。
3、然後點擊"用於解決方案"選項。
4、最後在打開的窗口中就可以查看到代碼度量值結果。
❷ 什麼叫圈復雜度(cyclomatic complexity)為什麼它很重要
1、圈復雜度:圈復雜度(Cyclomatic complexity)是一種代碼復雜度的衡量標准,在1976年由Thomas J. McCabe, Sr. 提出。
2、重要性:程序的可能錯誤和高的圈復雜度有著很大關系。
在軟體測試的概念里,圈復雜度用來衡量一個模塊判定結構的復雜程度,數量上表現為線性無關的路徑條數,即合理的預防錯誤所需測試的最少路徑條數。圈復雜度大說明程序代碼可能質量低且難於測試和維護。
(2)代碼質量度量模型擴展閱讀:
下面的列表顯示了Visual Studio( VS 2008 Team Suite Edition)計算的代碼度量結果:
可維護性指數:計算一個介於 0 和 100 之間的指數值,表示維護代碼的相對容易度。值越大表示可維護性越好。該計算基於 Halstead Volume、圈復雜度和代碼的行數。按顏色標記的等級可用於迅速發現代碼中的故障點。
綠色等級介於 20 和 100 之間,表示代碼的可維護性良好。黃色等級介於 10 和 19 之間,表示代碼的可維護性中等。紅色等級是介於 0 和 9 之間的等級,表示可維護性低。
圈復雜度:衡量代碼在結構上的復雜程度。它通過計算程序流中的不同代碼路徑的數目(例如 if 塊、switch case 以及 do、while、foreach 和 for 循環),然後在總數中加 1 來創建。具有復雜控制流的程序需要更多單元測試才能實現良好的代碼覆蓋率,並且不容易維護。
繼承深度:指明擴展到類層次結構根的類定義的數目。層次結構越深,則越難了解特定方法和欄位是在何處定義或/和重新定義的。
在類級別,該數目是通過計算繼承樹中從 0 開始的類型之上的類型數目(不包括介面)來創建的。在命名空間和項目級別,該計算包括命名空間或項目內所有類型的最高繼承深度計算。
類耦合:通過參數、局部變數、返回類型、方法調用、泛型或模板實例化、基類、介面實現、在外部類型上定義的欄位以及屬性修飾來衡量與唯一類的耦合程度。該計算不包括基元類型和內置類型,例如 int32、字元串和對象。
良好的軟體設計要求類型和方法應具有較高的內聚力和較低的耦合。耦合較高表示設計難以重用和維護,這是因為它與其他類型之間存在許多依存關系。
代碼的行數:指明代碼中的大概行數。該計數基於 IL 代碼,因此並不是源代碼文件中的確切行數。該計算不包括空白、注釋、括弧以及成員、類型和命名空間的聲明。計數過高可能表示某個類型或方法正在嘗試執行過多的工作,應予以拆分。還可能表示該類型或方法難以維護。
❸ 一堂如何提高代碼質量的培訓課
今天這堂培訓課講什麼呢?我既不講Spring,也不講Hibernate,更不講Ext,我不講任何一個具體的技術。我們拋開任何具體的技術,來談談如何提高代碼質量。如何提高代碼質量,相信不僅是在座所有人苦惱的事情,也是所有軟體項目苦惱的事情。如何提高代碼質量呢,我認為我們首先要理解什麼是高質量的代碼。 高質液搏量代碼的三要素 我們評價高質量代碼有三要素:可讀性、可維護性、可變更性。我們的代碼要一個都不能少地達到了這三要素的要求才能算高質量的代碼。 1. 可讀性強 一提到可讀性似乎有一些老生常談的味道,但令人沮喪的是,雖然大家一而再,再而三地強調可讀性,但我們的代碼在可讀性方面依然做得非常糟糕。由於工作的需要,我常常需要去閱讀他人的代碼,維護他人設計的模塊。每當我看到大段大段、密密麻麻的代碼,而且還沒有任何的注釋時常常感慨不已,深深體會到了這項工作的重要。由於分孝埋唯工的需要,我們寫的代碼難免需要別人去閱讀和維護的。而對於許多程序員來說,他們很少去閱讀和維巧培護別人的代碼。正因為如此,他們很少關注代碼的可讀性,也對如何提高代碼的可讀性缺乏切身體會。有時即使為代碼編寫了注釋,也常常是注釋語言晦澀難懂形同天書,令閱讀者反復斟酌依然不明其意。針對以上問題,我給大家以下建議: 1)不要編寫大段的代碼 如果你有閱讀他人代碼的經驗,當你看到別人寫的大段大段的代碼,而且還不怎麼帶注釋,你是怎樣的感覺,是不是「嗡」地一聲頭大。各種各樣的功能糾纏在一個方法中,各種變數來回調用,相信任何人多不會認為它是高質量的代碼,但卻頻繁地出現在我們編寫的程序了。如果現在你再回顧自己寫過的代碼,你會發現,稍微編寫一個復雜的功能,幾百行的代碼就出去了。一些比較好的辦法就是分段。將大段的代碼經過整理,分為功能相對獨立的一段又一段,並且在每段的前端編寫一段注釋。這樣的編寫,比前面那些雜亂無章的大段代碼確實進步了不少,但它們在功能獨立性、可復用性、可維護性方面依然不盡人意。從另一個比較專業的評價標准來說,它沒有實現低耦合、高內聚。我給大家的建議是,將這些相對獨立的段落另外封裝成一個又一個的函數。 許多大師在自己的經典書籍中,都鼓勵我們在編寫代碼的過程中應當養成不斷重構的習慣。我們在編寫代碼的過程中常常要編寫一些復雜的功能,起初是寫在一個類的一個函數中。隨著功能的逐漸展開,我們開始對復雜功能進行歸納整理,整理出了一個又一個的獨立功能。這些獨立功能有它與其它功能相互交流的輸入輸出數據。當我們分析到此處時,我們會非常自然地要將這些功能從原函數中分離出來,形成一個又一個獨立的函數,供原函數調用。在編寫這些函數時,我們應當仔細思考一下,為它們取一個釋義名稱,並為它們編寫注釋(後面還將詳細討論這個問題)。另一個需要思考的問題是,這些函數應當放到什麼地方。這些函數可能放在原類中,也可能放到其它相應職責的類中,其遵循的原則應當是「職責驅動設計」(後面也將詳細描述)。 下面是我編寫的一個從XML文件中讀取數據,將其生成工廠的一個類。這個類最主要的一段程序就是初始化工廠,該功能歸納起來就是三部分功能:用各種方式嘗試讀取文件、以DOM的方式解析XML數據流、生成工廠。而這些功能被我歸納整理後封裝在一個不同的函數中,並且為其取了釋義名稱和編寫了注釋: Java代碼/** * 初始化工廠。根據路徑讀取XML文件,將XML文件中的數據裝載到工廠中 * @param path XML的路徑 */publicvoid initFactory(String path){ if(findOnlyOneFileByClassPath(path)){return;} if(findResourcesByUrl(path)){return;} if(findResourcesByFile(path)){return;} this.paths = new String[]{path}; } /** * 初始化工廠。根據路徑列表依次讀取XML文件,將XML文件中的數據裝載到工廠中 * @param paths 路徑列表 */publicvoid initFactory(String[] paths){ for(int i=0; i>Java>>Code Style>>Code Templates>>Comments」中,可以簡單的修改一下。 「Files」代表的是我們每新建一個文件(可能是類也可能是介面)時編寫的注釋,我通常設定為: Java代碼/* * created on ${date} */ 「Types」代表的是我們新建的介面或類前的注釋,我通常設定為: Java代碼/** * * @author ${user} */ 第一行為一個空行,是用於你寫該類的注釋。如果你採用「職責驅動設計」,這里首先應當描述的是該類的職責。如果需要,你可以寫該類一些重要的方法及其用法、該類的屬性及其中文含義等。 ${user}代表的是你在windows中登陸的用戶名。如果這個用戶名不是你的名稱,你可以直接寫死為你自己的名稱。 其它我通常都保持為默認值。通過以上設定,你在創建類或介面的時候,系統將自動為你編寫好注釋,然後你可以在這個基礎上進行修改,大大提高注釋編寫的效率。 同時,如果你在代碼中新增了一個函數時,通過Alt+Shift+J快捷鍵,可以按照模板快速添加註釋。 在編寫代碼時如果你編寫的是一個介面或抽象類,我還建議你在@author後面增加@see注釋,將該介面或抽象類的所有實現類列出來,因為閱讀者在閱讀的時候,尋找介面或抽象類的實現類比較困難。 Java代碼/** * 抽象的單表數組查詢實現類,僅用於單表查詢 * @author 范鋼* @see com.htxx.support.query.DefaultArrayQuery * @see com.htxx.support.query.DwrQuery */publicabstractclass ArrayQuery implements ISingleQuery { ... 2. 可維護性 軟體的可維護性有幾層意思,首先的意思就是能夠適應軟體在部署和使用中的各種情況。從這個角度上來說,它對我們的軟體提出的要求就是不能將代碼寫死。 1)代碼不能寫死 我曾經見我的同事將系統要讀取的一個日誌文件指定在C盤的一個固定目錄下,如果系統部署時沒有這個目錄以及這個文件就會出錯。如果他將這個決定路徑下的目錄改為相對路徑,或者通過一個屬性文件可以修改,代碼豈不就寫活了。一般來說,我在設計中需要使用日誌文件、屬性文件、配置文件,通常都是以下幾個方式:將文件放到與類相同的目錄,使用ClassLoader.getResource()來讀取;將文件放到classpath目錄下,用File的相對路徑來讀取;使用web.xml或另一個屬性文件來制定讀取路徑。 我也曾見另一家公司的軟體要求,在部署的時候必須在C:/bea目錄下,如果換成其它目錄則不能正常運行。這樣的設定常常為軟體部署時帶來許多的麻煩。如果伺服器在該目錄下已經沒有多餘空間,或者已經有其它軟體,將是很撓頭的事情。 2)預測可能發生的變化 除此之外,在設計的時候,如果將一些關鍵參數放到配置文件中,可以為軟體部署和使用帶來更多的靈活性。要做到這一點,要求我們在軟體設計時,應當有更多的意識,考慮到軟體應用中可能發生的變化。比如,有一次我在設計財務軟體的時候,考慮到一些單據在製作時的前置條件,在不同企業使用的時候,可能要求不一樣,有些企業可能要求嚴格些而有些要求鬆散些。考慮到這種可能的變化,我將前置條件設計為可配置的,就可能方便部署人員在實際部署中進行靈活變化。然而這樣的配置,必要的注釋說明是非常必要的。 軟體可維護性的另一層意思就是軟體的設計便於日後的變更。這一層意思與軟體的可變更性是重合的。所有的軟體設計理論的發展,都是從軟體的可變更性這一要求逐漸展開的,它成為了軟體設計理論的核心。 3. 可變更性 前面我提到了,軟體的變更性是所有軟體理論的核心,那麼什麼是軟體的可變更性呢?按照現在的軟體理論,客戶對軟體的需求時時刻刻在發生著變化。當軟體設計好以後,為應對客戶需求的變更而進行的代碼修改,其所需要付出的代價,就是軟體設計的可變更性。由於軟體合理的設計,修改所付出的代價越小,則軟體的可變更性越好,即代碼設計的質量越高。一種非常理想的狀態是,無論客戶需求怎樣變化,軟體只需進行適當的修改就能夠適應。但這之所以稱之為理想狀態,因為客戶需求變化是有大有小的。如果客戶需求變化非常大,即使再好的設計也無法應付,甚至重新開發。然而,客戶需求的適當變化,一個合理的設計可以使得變更代價最小化,延續我們設計的軟體的生命力。 1)通過提高代碼復用提高可維護性 我曾經遇到過這樣一件事,我要維護的一個系統因為應用范圍的擴大,它對機關級次的計算方式需要改變一種策略。如果這個項目統一採用一段公用方法來計算機關級次,這樣一個修改實在太簡單了,就是修改這個公用方法即可。但是,事實卻不一樣,對機關級次計算的代碼遍布整個項目,甚至有些還寫入到了那些復雜的SQL語句中。在這樣一種情況下,這樣一個需求的修改無異於需要遍歷這個項目代碼。這樣一個實例顯示了一個項目代碼復用的重要,然而不幸的是,代碼無法很好復用的情況遍布我們所有的項目。代碼復用的道理十分簡單,但要具體運作起來非常復雜,它除了需要很好的代碼規劃,還需要持續地代碼重構。 對整個系統的整體分析與合理規劃可以根本地保證代碼復用。系統分析師通過用例模型、領域模型、分析模型的一步一步分析,最後通過正向工程,生成系統需要設計的各種類及其各自的屬性和方法。採用這種方法,功能被合理地劃分到這個類中,可以很好地保證代碼復用。 採用以上方法雖然好,但技術難度較高,需要有高深的系統分析師,並不是所有項目都能普遍採用的,特別是時間比較緊張的項目。通過開發人員在設計過程中的重構,也許更加實用。當某個開發人員在開發一段代碼時,發現該功能與前面已經開發功能相同,或者部分相同。這時,這個開發人員可以對前面已經開發的功能進行重構,將可以通用的代碼提取出來,進行相應的改造,使其具有一定的通用性,便於各個地方可以使用。 一些比較成功的項目組會指定一個專門管理通用代碼的人,負責收集和整理項目組中各個成員編寫的、可以通用的代碼。這個負責人同時也應當具有一定的代碼編寫功力,因為將專用代碼提升為通用代碼,或者以前使用該通用代碼的某個功能,由於業務變更,而對這個通用代碼的變更要求,都對這個負責人提出了很高的能力要求。 雖然後一種方式非常實用,但是它有些亡羊補牢的味道,不能從整體上對項目代碼進行有效規劃。正因為兩種方法各有利弊,因此在項目中應當配合使用。 2)利用設計模式提高可變更性 對於初學者,軟體設計理論常常感覺晦澀難懂。一個快速提高軟體質量的捷徑就是利用設計模式。這里說的設計模式,不僅僅指經典的32個模式,是一切前人總結的,我們可以利用的、更加廣泛的設計模式。 a. if...else... 這個我也不知道叫什麼名字,最早是哪位大師總結的,它出現在Larman的《UML與模式應用》,也出現在出現在Mardin的《敏捷軟體開發》。它是這樣描述的:當你發現你必須要設計這樣的代碼:「if...elseif...elseif...else...」時,你應當想到你的代碼應當重構一下了。我們先看看這樣的代碼有怎樣的特點。 Java代碼if(var.equals("A")){ doA(); } elseif(var.equals("B")){ doB(); } elseif(var.equals("C")){ doC(); } else{ doD(); } 這樣的代碼很常見,也非常平常,我們大家都寫過。但正是這樣平常才隱藏著我們永遠沒有注意的問題。問題就在於,如果某一天這個選項不再僅僅是A、B、C,而是增加了新的選項,會怎樣呢?你也許會說,那沒有關系,我把代碼改改就行。然而事實上並非如此,在大型軟體研發與維護中有一個原則,每次的變更盡量不要去修改原有的代碼。如果我們重構一下,能保證不修改原有代碼,僅僅增加新的代碼就能應付選項的增加,這就增加了這段代碼的可維護性和可變更性,提高了代碼質量。那麼,我們應當如何去做呢? 經過深入分析你會發現,這里存在一個對應關系,即A對應doA(),B對應doB()...如果將doA()、doB()、doC()...與原有代碼解耦,問題就解決了。如何解耦呢?設計一個介面X以及它的實現A、B、C...每個類都包含一個方法doX(),並且將doA()的代碼放到A.doX()中,將doB()的代碼放到B.doX()中...經過以上的重構,代碼還是這些代碼,效果卻完全不一樣了。我們只需要這樣寫: Java代碼X x = factory.getBean(var); x.doX(); 這樣就可以實現以上的功能了。我們看到這里有一個工廠,放著所有的A、B、C...並且與它們的key對應起來,並且寫在配置文件中。如果出現新的選項時,通過修改配置文件就可以無限制的增加下去。 這個模式雖然有效提高了代碼質量,但是不能濫用,並非只要出現if...else...就需要使用。由於它使用了工廠,一定程度上增加了代碼復雜度,因此僅僅在選項較多,並且增加選項的可能性很大的情況下才可以使用。另外,要使用這個模式,繼承我在附件中提供的抽象類XmlBuildFactoryFacade就可以快速建立一個工廠。如果你的項目放在spring或其它可配置框架中,也可以快速建立工廠。設計一個Map靜態屬性並使其V為這些A、B、C...這個工廠就建立起來了。 b. 策略模式 也許你看過策略模式(strategy model)的相關資料但沒有留下太多的印象。一個簡單的例子可以讓你快速理解它。如果一個員工系統中,員工被分為臨時工和正式工並且在不同的地方相應的行為不一樣。在設計它們的時候,你肯定設計一個抽象的員工類,並且設計兩個繼承類:臨時工和正式工。這樣,通過下溯類型,可以在不同的地方表現出臨時工和正式工的各自行為。在另一個系統中,員工被分為了銷售人員、技術人員、管理人員並且也在不同的地方相應的行為不一樣。同樣,我們在設計時也是設計一個抽象的員工類,並且設計數個繼承類:銷售人員、技術人員、管理人員。現在,我們要把這兩個系統合並起來,也就是說,在新的系統中,員工既被分為臨時工和正式工,又被分為了銷售人員、技術人員、管理人員,這時候如何設計。如果我們還是使用以往的設計,我們將不得不設計很多繼承類:銷售臨時工、銷售正式工、技術臨時工、技術正式工。。。如此的設計,在隨著劃分的類型,以及每種類型的選項的增多,呈笛卡爾增長。通過以上一個系統的設計,我們不得不發現,我們以往學習的關於繼承的設計遇到了挑戰。 解決繼承出現的問題,有一個最好的辦法,就是採用策略模式。在這個應用中,員工之所以要分為臨時工和正式工,無非是因為它們的一些行為不一樣,比如,發工資時的計算方式不同。如果我們在設計時不將員工類分為臨時工類和正式工類,而僅僅只有員工類,只是在類中增加「工資發放策略」。當我們創建員工對象時,根據員工的類型,將「工資發放策略」設定為「臨時工策略」或「正式工策略」,在計算工資時,只需要調用策略類中的「計算工資」方法,其行為的表現,也設計臨時工類和正式工類是一樣的。同樣的設計可以放到銷售人員策略、技術人員策略、管理人員策略中。一個通常的設計是,我們將某一個影響更大的、或者選項更少的屬性設計成繼承類,而將其它屬性設計成策略類,就可以很好的解決以上問題。 使用策略模式,你同樣把代碼寫活了,因為你可以無限制地增加策略。但是,使用策略模式你同樣需要設計一個工廠——策略工廠。以上實例中,你需要設計一個發放工資策略工廠,並且在工廠中將「臨時工」與「臨時工策略」對應起來,將「正式工」與「正式工策略」對應起來。 c. 適配器模式 我的筆記本是港貨,它的插頭與我們常用的插座不一樣,所有我出差的時候我必須帶一個適配器,才能使用不同地方的插座。這是一個對適配器模式最經典的描述。當我們設計的系統要與其它系統交互,或者我們設計的模塊要與其它模塊交互時,這種交互可能是調用一個介面,或者交換一段數據,接受方常常因發送方對協議的變更而頻繁變更。這種變更,可能是接受方來源的變更,比如原來是A系統,現在變成B系統了;也可能是接受方自身的代碼變更,如原來的介面現在增加了一個參數。由於發送方的變更常常導致接受方代碼的不穩定,即頻繁跟著修改,為接受方的維護帶來困難。 遇到這樣的問題,一個有經驗的程序員馬上想到的就是採用適配器模式。在設計時,我方的介面按照某個協議編寫,並且保持固定不變。然後,在與真正對方介面時,在前段設計一個適配器類,一旦對方協議發生變更,我可以換個適配器,將新協議轉換成原協議,問題就解決了。適配器模式應當包含一個介面和它的實現類。介面應當包含一個本系統要調用的方法,而它的實現類分別是與A系統介面的適配器、與B系統介面的適配器... 我曾經在一個項目中需要與另一個系統介面,起初那個系統通過一個數據集的方式為我提供數據,我寫了一個接收數據集的適配器;後來改為用一個XML數據流的形式,我又寫了一個接收XML的適配器。雖然為我提供數據的方式不同,但是經過適配器轉換後,輸出的數據是一樣的。通過在spring中的配置,我可以靈活地切換到底是使用哪個適配器。 d. 模板模式 32個經典模式中的模板模式,對開發者的代碼規劃能力提出了更高的要求,它要求開發者對自己開發的所有代碼有一個相互聯系和從中抽象的能力,從各個不同的模塊和各個不同的功能中,抽象出其過程比較一致的通用流程,最終形成模板。譬如說,讀取XML並形成工廠,是許多模塊常常要使用的功能。它們雖然有各自的不同,但是總體流程都是一樣的:讀取XML文件、解析XML數據流、形成工廠。正因為有這樣的特徵,它們可以使用共同的模板,那麼,什麼是模板模式呢? 模板模式(Template Model)通常有一個抽象類。在這個抽象類中,通常有一個主函數,按照一定地順序去調用其它函數。而其它函數往往是某這個連續過程中的各個步驟,如以上實例中的讀取XML文件、解析XML數據流、形成工廠等步驟。由於這是一個抽象類,這些步驟函數可以是抽象函數。抽象類僅僅定義了整個過程的執行順序,以及一些可以通用的步驟(如讀取XML文件和解析XML數據流),而另一些比較個性的步驟,則由它的繼承類自己去完成(如上例中的「形成工廠」,由於各個工廠各不一樣,因此由各自的繼承類自己去決定它的工廠是怎樣形成的)。 各個繼承類可以根據自己的需要,通過重載重新定義各個步驟函數。但是,模板模式要求不能重載主函數,因此正規的模板模式其主函數應當是final(雖然我們常常不這么寫)。另外,模板模式還允許你定義的這個步驟中,有些步驟是可選步驟。對與可選步驟,我們通常稱為「鉤子(hood)」。它在編寫時,在抽象類中並不是一個抽象函數,但卻是一個什麼都不寫的空函數。繼承類在編寫時,如果需要這個步驟則重載這個函數,否則就什麼也不寫,進而在執行的時候也如同什麼都沒有執行。 通過以上對模板模式的描述可以發現,模板模式可以大大地提高我們的代碼復用程度。 以上一些常用設計模式,都能使我們快速提高代碼質量。還是那句話,設計模式不是什麼高深的東西,恰恰相反,它是初學者快速提高的捷徑。然而,如果說提高代碼復用是提高代碼質量的初階,使用設計模式也只能是提高代碼質量的中階。那麼,什麼是高階呢?我認為是那些分析設計理論,更具體地說,就是職責驅動設計和領域驅動設計。 3)職責驅動設計和領域驅動設計 前面我提到,當我們嘗試寫一些復雜功能的時候,我們把功能分解成一個個相對獨立的函數。但是,應當將這些函數分配到哪個類中呢?也就是系統中的所有類都應當擁有哪些函數呢?或者說應當表現出哪些行為呢?答案就在這里:以職責為中心,根據職責分配行為。我們在分析系統時,首先是根據客戶需求進行用例分析,然後根據用例繪制領域模式和分析模型,整個系統最主要的類就形成了。通過以上分析形成的類,往往和現實世界的對象是對應的。正因為如此,軟體世界的這些類也具有了與現實世界的對象相對應的職責,以及在這些職責范圍內的行為。 職責驅動設計(Responsibility Drive Design,RDD)是Craig Larman在他的經典著作《UML和模式應用》中提出的。職責驅動設計的核心思想,就是我們在對一個系統進行分析設計的時候,應當以職責為中心,根據職責分配行為。這種思想首先要求我們設計的所有軟體世界的對象,應當與現實世界盡量保持一致,他稱之為「低表示差異」。有了低表示差異,一方面提高了代碼的可讀性,另一方面,當業務發生變更的時候,也可以根據實際情況快速應對變更。 Craig Larman在提出職責驅動設計理論的同時,還提出了GRASP設計模式,來豐富這個理論。在GRASP設計模式中,我認為,低耦合、高內聚、信息專家模式最有用。 繼Craig Larman提出的職責驅動設計數年之後,另一位大師提出了領域驅動設計。領域驅動設計(Domain Drive Design,DDD)是Eric Evans在他的同名著作《領域驅動設計》中提出的。在之前的設計理論中,領域模型是從用例模型到分析模型之間的一種中間模型,也就是從需求分析到軟體開發之間的一種中間模型。這么一個中間模型,既不是需求階段的重要產物,在開發階段也不以它作為標准進行開發,僅僅是作為參考,甚至給人感覺有一些多餘。但是,Evans在領域驅動設計中,將它放到了一個無比重要的位置。按照領域驅動設計的理論,在需求分析階段,需求分析人員使用領域模型與客戶進行溝通;在設計開發階段,開發人員使用領域模型指導設計開發;在運行維護和二次開發階段,維護和二次開發人員使用領域模型理解和熟悉系統,並指導他們進行維護和二次開發。總之,在整個軟體開發的生命周期中,領域模型都成為了最核心的內容。 領域驅動設計繼承了職責驅動設計。在領域驅動設計中強調的,依然是低表示差異,以及職責的分配。但是,如何做到低表示差異呢?如何完成職責分配呢?領域驅動設計給了我們完美的答案,那就是建立領域模型。領域驅動設計改變了我們的設計方式。在需求分析階段,用例模型已不再是這個階段的核心,而是建立領域模型。在開發和二次開發階段,開發人員也不再是一埋頭地猛扎進程序堆里開始編程,而是首先細致地進行領域模型分析。領域驅動設計強調持續精化,使領域模型不再是一旦完成分析就扔在一邊不再理會的圖紙,而是在不斷理解業務的基礎上不斷修改和精化領域模型,進而驅動我們代碼的精化。領域驅動設計強調的不再是一次軟體開發過程中我們要做的工作,它看得更加長遠,它強調的是一套軟體在相當長一段時間內持續升級的過程中我們應當做的工作。我認為,領域驅動設計是提高代碼質量的最高等級。當時,使用領域驅動設計進行軟體開發是一場相當巨大的改革,它顛覆了我們過去的所有開發模式,我們必須腳踏實地地一步一步去實踐和改變。 職責驅動設計 隨著軟體業的不斷發展,隨著軟體需求的不斷擴大,軟體所管理的范圍也在不斷拓寬。過去一個軟體僅僅管理一台電腦的一個小小的功能,而現在被擴展到了一個企業、一個行業、一個產業鏈。過去我們開發一套軟體,只有少量的二次開發,當它使用到一定時候我們就拋棄掉重新又開發一套。現在,隨著用戶對軟體依賴程度的不斷加大,我們很難說拋棄一套軟體重新開發了,更多的是在一套軟體中持續改進,使這套軟體的生命周期持續數年以及數個版本。正是因為軟體業面臨著如此巨大的壓力,我們的代碼質量,我們開發的軟體擁有的可變更性和持續改進的能力,成為軟體制勝的關鍵因素,令我們不能不反思。 代碼質量評價的關鍵指標:低耦合,高內聚 耦合就是對某元素與其它元素之間的連接、感知和依賴的量度。耦合包括: 1.元素B是元素A的屬性,或者元素A引用了元素B的實例(這包括元素A調用的某個方法,其參數中包含元素B)。 2.元素A調用了元素B的方法。 3.元素A直接或間接成為元素B的子類。 4.元素A是介面B的實現。 如果一個元素過於依賴其它元素,一旦它所依賴的元素不存在,或者發生變更,則該元素將不能再正常運行,或者不得不相應地進行變更。因此,耦合將大大影響代碼的通用性和可變更性。 內聚,更為專業的說法叫功能內聚,是對軟體系統中元素職責相關性和集中度的度量。如果元素具有高度相關的職責,除了這些職責內的任務,沒有其它過多的工作,那麼該元素就具有高內聚性,反之則為低內聚性。內聚就像一個專橫的管理者,它只做自己職責范圍內的事,而將其它與它相關的事情,分配給別人去做。 高質量的代碼要求我們的代碼保持低耦合、高內聚。但是,這個要求是如此的抽象與模糊,如何才能做到這些呢?軟體大師們告訴我們了許多方法,其中之一就是Craig Larman的職責驅動設計。 職責驅動設計(Responsibility Drive Design,RDD)是Craig Larman在他的經典著作《UML和模式應用》中提出的。要理解職責驅動設計,我們首先要理解「低表示差異」。 低表示差異 我們開發的應用軟體實際上是對現實世界的模擬,因此,軟體世界與現實世界存在著必然的聯系。當我們在進行需求分析的時候,需求分析員實際上是從客戶那裡在了解現實世界事物的規則、工作的流程。如果我們在軟體分析和設計的過程中,將軟體世界與現實世界緊密地聯繫到一起,我們的軟體將更加本色地還原事物最本質的規律。這樣的設計,就稱之為「低表示差異」。 採用「低表示差異」進行軟體設計,現實世界有什麼事物,就映射為軟體世界的各種對象(類);現實世界的事物擁有什麼樣的職責,在軟體世界裡的對象就擁有什麼樣的職責;在現實世界中的事物,因為它的職責而產生的行為,在軟體世界中就反映為對象所擁有的函數。 低表示差異,使分析設計者對軟體的分析和設計更加簡單,思路更加清晰;使代碼更加可讀,閱讀者更加易於理解;更重要的是
❹ 靜態測試的定義
靜態測試包括代碼檢查、靜態結構分析、代碼質量度量等。它可以由人工進行,充分發揮人專的邏屬輯思維優勢,也可以藉助軟體工具自動進行。代碼檢查包括代碼走查、桌面檢查、代碼審查等,主要檢查代碼和設計的一致性,代碼對標準的遵循、可讀性,代碼的邏輯表達的正確性,代碼結構的合理性等方面;可以發現違背程序編寫標準的問題,程序中不安全、不明確和模糊的部分,找出程序中不可移植部分、違背程序編程風格的問題,包括變數檢查、命名和類型審查、程序邏輯審查、程序語法檢查和程序結構檢查等內容。
在實際使用中,代碼檢查比動態測試更有效率,能快速找到缺陷,發現30%~70%的邏輯設計和編碼缺陷;代碼檢查看到的是問題本身而非徵兆。但是代碼檢查非常耗費時間,而且代碼檢查需要知識和經驗的積累。代碼檢查應在編譯和動態測試之前進行,在檢查前,應准備好需求描述文檔、程序設計文檔、程序的源代碼清單、代碼編碼標准和代碼缺陷檢查表等。靜態測試具有的發現缺陷早、降低返工成本、覆蓋重點和發現缺陷的概率高的優點以及耗時長、不能測試依賴和技術能力要求高的缺點。