簡體   English   中英

如何在if-else語句中減少Cyclomatic復雜性

[英]How to reduce Cyclomatic complexity in an if-else statement

在這種情況下,您將采取什么措施來減少Cyclomatic Complexty

if (Name.Text == string.Empty)
    Name.Background = Brushes.LightSteelBlue;

else if(Age.Text == string.Empty)
    Age.Background = Brushes.LightSteelBlue;

else if(...)
    ...

else
{
    // TODO - something else
}

假設我有30個或更多。

看起來你在每個“TextBox”上執行相同的邏輯(至少我認為它們是TextBoxes)。 我建議將所有這些都放入一個集合中並執行以下邏輯:

// Using var, since I don't know what class Name and Age actually are
// I am assuming that they are most likely actually the same class
// and at least share a base class with .Text and .BackGround
foreach(var textBox in textBoxes)
{
    // Could use textBox.Text.Length > 0 here as well for performance
    if(textBox.Text == string.Empty)
    {
        textBox.Background = Brushes.LightSteelBlue;
    }
}

注意:這確實會改變你的代碼,因為我注意到你只檢查一個“TextBox”的值,只有前面的那些沒有空文本。 如果你想保持這種邏輯,只需break; textBox.Background = Brushes.LightSteelBlue;之后的語句textBox.Background = Brushes.LightSteelBlue; 並且只有第一個空的“TextBox”才會設置其背景顏色。

例如,對於這個具體案例,你可以

  • 定義一個Dictionary<string, dynamic> dic ,其中KEY是一個字符串值 ,VALUE是動態的( NameAge ...... whatever)

  • do dic [stringValue] .Background = Color.LightSteelBlue;

只是一個例子。

可能想要選擇是否dynamic 可能更直觀,更容易理解,但基本思路是:

根據if正確值使用帶有鍵的字典,並且像某個操作/方法/對象的值一樣使用。

希望這可以幫助。

我完全贊同svick的評論。 在某些情況下,以下方法可能是好的(但不是為了減少圈復雜度,通常是為了創建可插拔的決策者):

public class SwitchAction{
  public Func<bool> Predicate { get; set; }
  public Action TheAction { get; set; }
}

public List<SwitchAction> SwitchableActions = new List<SwitchAction>();

public void InitialiseSwitchableActions()
{
   SwitchableActions.AddRange(new[] {
     new SwitchAction() { Predicate = () => Name.Text == string.Empty, 
                          TheAction = () => Name.Background = Brushes.LightSteelBlue },
     new SwitchAction() { Predicate = () => Age.Text == string.Empty, 
                          TheAction = () => Age.Background = Brushes.LightSteelBlue },
   });
}

public void RunSwitchables()
{
  var switched = SwitchableActions.FirstOrDefault(s => Predicate());

  if(switched != null)
    switched.TheAction();
  else
    //TODO: something else.
}

當然 - 如果實際上這些動作不是相互排斥的,你必須稍微改變最后一個方法:

public void RunSwitchables()
{
   bool runCatchAll = true;
   foreach(var switched in SwitchableActions.Where(a => a.Predicate())
   {
     switched.TheAction();
     runCatchAll = false;
   }

   if(runCatchAll)
     //TODO: Something else.
}

這些中的任何一個都更具可讀性嗎? 嗯...可能不是。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM