2010-05-29 60 views
10

至於誰愛遵循最佳實踐的人,Visual Studio的代碼度量和開關箱的可維護性指數

如果我運行代碼度量(在解決方案資源管理器中的項目名稱點擊右鍵,選擇「計算代碼度量」 - 在Visual Studio 2010中):

public static string GetFormFactor(int number) 
    { 
     string formFactor = string.Empty; 
     switch (number) 
     { 
      case 1: 
       formFactor = "Other"; 
       break; 

      case 2: 
       formFactor = "SIP"; 
       break; 

      case 3: 
       formFactor = "DIP"; 
       break; 

      case 4: 
       formFactor = "ZIP"; 
       break; 

      case 5: 
       formFactor = "SOJ"; 
       break; 
     } 

     return formFactor; 
    } 

它給我的

可維護性指數(當然這是微不足道的,如果你只有這一點,但如果你使用像類衛生組織PHILOS的效用ophy正在做這樣的事情,你的公用事業類別的可維護性指數將會差得多。)

這是什麼解決方案?

回答

26

首先:61被認爲是可維護的代碼。對於可維護性指數,100很容易維護代碼,而0很難維護。

  • 0-9 =難以維持
  • 10-19 =中等維持
  • 20-100 =好,以保持

可維護性指數是基於三個代碼度量:即的霍爾斯特德Volumen,圈複雜度和代碼行並基於following formula

MAX(0,(171 - 5.2 * LN(霍爾斯特德 卷) - 0.23 *(秩 複雜性) - 16.2 * LN( 代碼行))* 100/171)

事實上,在您的示例的根本原因的維護性指數的低值是圓形複雜性。該度量基於代碼中的各種執行路徑進行計算。不幸的是,該指標不一定與代碼的「人類可讀性」保持一致。

作爲代碼的例子導致索引值非常低(記住,下限意味着難以維護),但實際上它們非常容易閱讀。當使用Cyclomatic Complexity評估代碼時,這很常見。

想象一下對於幾天(週一至週日)加上一個開關塊(1月至12月)的開關塊的代碼。此代碼將非常易讀和可維護,但會導致巨大的環路複雜性,因此Visual Studio 2010中的可維護性指數非常低。

這是一個衆所周知的關於度量標準的事實,如果代碼被判斷根據數字。應該隨時監測數字,而不是查看絕對數字,以瞭解代碼更改的指標。例如。如果可維護性指數始終爲100,並突然下降到10,則應檢查造成這種情況的變化。

+0

注意:該索引基於_average_ HV,CC和LOC。有關可維護性指數,係數,閾值及其歷史的進一步分析,請參閱我的博客文章「[在使用可維護性指數前思考兩次]」(http://avandeursen.com/2014/08/29/think- /),使用最可維護性指數兩次先接後「。 – avandeursen 2014-09-11 16:34:06

2

兩件事情映入腦海:

使用枚舉說明書和值

public enum FormFactor 
{ 
    Other = 1, 
    SIP = 2, 
    etc. 
} 

使用一個類或結構來表示每個形狀因數

public class FormFactor 
{ 
    public int Index { get; private set; } 
    public string Description { get; private set; } 

    public FormFactor(int index, string description) 
    { 
     // do validation and assign properties 
    } 
} 
結婚了
+0

嗯,我有一些難以理解你的解決方案。你可以請更具體一點嗎?一個更詳細的例子? 關注 – pee2002 2010-05-29 22:52:44

0

我不知道它有多重要,但下面得到一個76:

private static string[] _formFactors = new[] { null, "Other","SIP","DIP", "ZIP", "SOJ"}; 
public static string GetFormFactor2(int number) 
{ 
    if (number < 1 || number > _formFactors.Length) 
    { 
     throw new ArgumentOutOfRangeException("number"); 
    } 

    return _formFactors[number]; 
} 
+0

是的,它的解決方案,但沒有太多優雅的一個:P我在想這樣做的結構方式。有任何想法嗎? – pee2002 2010-05-29 23:18:12

2

我會做這種方式,而忘記了可維護性指數:

public static string GetFormFactor(int number) 
{ 
    switch (number) 
    { 
     case 1: return "Other"; 
     case 2: return "SIP"; 
     case 3: return "DIP"; 
     case 4: return "ZIP"; 
     case 5: return "SOJ"; 
    } 

    return number.ToString(); 
} 

恕我直言,容易閱讀和容易改變。

+0

這就是我做的..但我真的想知道是否有另一種解決方案 – pee2002 2010-05-29 23:29:50

+0

我發現下面提到的數組和枚舉方法的可讀性和可維護性較差。 – 2010-05-30 07:44:52

0

很明顯對我來說枚舉方法是最容易維護的,因爲它不涉及硬編碼的字符串,因此沒有錯字問題和編譯時語法檢查。 只有限制是命名規則。

5

可維護性指數可能會更高,因爲您選擇的解決方案缺少可擴展性。

正確的解決方案(Mark Simpson上面提到的)是一種可以擴展爲使用新外形因子而不需要重建代碼的代碼 - 代碼中的switch/case語句總是表示OO設計已被遺忘,應該總是被視爲糟糕的代碼味道。

就個人而言,我會實現......

interface IFormFactor 
{ 
    // some methods 
} 

class SipFormFactor : IFormFactor... 

class DipFormFactor : IFormFactor... 

Etc. 

...並有接口的方法提供所需的功能 - 你可以把它想象[我猜]作爲中GoF的命令相似模式。

這樣你更高級別的方法可以只是......

MyMethod(IFormFactor factor) 
{ 
    // some logic... 

    factor.DoSomething(); 

    // some more logic... 
} 

...你可以在以後的日子一起去,也無需更改此代碼,你會引入新的形式因素用硬編碼的switch條款。你也會發現這種方法也很容易讓TDD(如果你正在做TDD,你最終會得到這個結果),因爲它很容易被嘲笑。

3

我知道這個答案很晚,但我感興趣的是沒有人提出字典解決方案呢。我發現,在處理像這樣的面向數據的巨大開關語句時,通常將開關案例摺疊成字典更具可讀性。

public static readonly IDictionary<int, string> Factors = new Dictionary<int, string> { 
    { 1, "Other" }, 
    { 2, "SIP" }, 
    { 3, "DIP" }, 
    { 4, "ZIP" }, 
    { 5, "SOJ" } 
}; 

public static string GetFormFactor2(int number) 
{ 
    string formFactor = string.Empty; 
    if (Factors.ContainsKey(number)) formFactor = Factors[number]; 
    return formFactor; 
} 

這給你的74可維護性指數 - 不是因爲類耦合到字典的陣列解決方案略低,但我覺得這是更普遍的,因爲它可以用於任何數量的類型,你通常會打開。與陣列解決方案一樣,它的擴展性非常好,並消除了大量重複性代碼。

一般來說,使用數據驅動的方法可以幫助你的代碼更清晰,因爲它將重要的部分(在這種情況下,條件和結果)從cruft中分離出來(在這種情況下,switch-case )。

相關問題