簡體   English   中英

編碼模式c#

[英]Coding pattern c#

前幾天我在代碼審查中遇到了一些看起來像這樣的代碼。

public void DoSomeTasks()
{
  if (CheckSomeState()==true) return;
    DoTaskOne();
  if (CheckSomeState()==true) return;
    DoTaskTwo();
  if (CheckSomeState()==true) return;
    DoTaskThree();
  if (CheckSomeState()==true) return;
    DoTaskFour(); 
}

隨着任務數量的增加,代碼最終會出現更高的圈復雜度,而且對我來說也感覺不對。

我提出解決這個問題的解決方案是。

private void DoTasksWhile(Func<bool> condition, Action[] tasks)
{
   foreach (var task in tasks)
   {
      if (condition.Invoke()==false) break;
        task.Invoke();
   }
}

像這樣使用

public void DoSomeTasks()
{
 var tasks = new Action[] { 
  {()=DoTaskOne()},
  {()=DoTaskTwo()},
  {()=DoTaskThree()},
  {()=DoTaskFour()}

  }

  DoTasksWhile(()=>CheckSomeState(), tasks);
}

有人有任何建議讓代碼更具可讀性嗎?

我對你的實現進行了一些重構

private void DoTasksWhile(Func<bool> predicate, IEnumerable<Action> tasks)
{
    foreach (var task in tasks)
    {
        if (!predicate())
            return;
        task();
    }
}
  • 您不需要Invoke委托。 只需執行它們
  • 不要將布爾值與true/false進行比較(它沒用,你可以錯誤地指定布爾值)
  • 因此你只枚舉任務, IEnumerable適用於參數

您也可以創建擴展方法

public static void DoWhile(this IEnumerable<Action> actions,Func<bool> predicate)
{
    foreach (var action in actions)
    {
        if (!predicate())
            return;
        actions();
    }
}

用法很簡單:

tasks.DoWhile(() => CheckSomeState());

如果您的業務流程代碼非常復雜,請考慮使用WF(工作流基礎)等框架。

否則,您的代碼很好,但我不會更改初始代碼,因為它更具可讀性。 它也更靈活,因為將來您可以修改這些IF,即條件可能不會保持相同。

我不知道如何降低或減少圈復雜度。

你的解決方案完全足夠(雖然在四個步驟的情況下可能有點過分),但在這種情況下它是否是最好的方法取決於CheckSomeState在你的程序環境中的實際目的:

  • 在每個任務之間只調用一次CheckSomeState是否重要?
  • 它有時也需要在任務中途調用嗎?

因此,例如,如果CheckSomeState實際上正在檢查取消標志,那么在長時間運行的任務中可能需要額外的檢查。

您可以使用的另一個選項是拋出異常(例如,OperationCancelledException)。 這可以使你的圈復雜度非常低,你現在可以簡單地做到:

CheckForCancel();
DoTaskOne();
CheckForCancel();
DoTaskTwo();

(缺點是有些人會認為這是使用控制流程的例外,這通常是不贊成的)。

我還應該補充一點,目標不應該是減少圈復雜度,而是要使代碼易於理解和維護。 循環復雜性是一個有用的指標,但它有時會不必要地懲罰非常簡單的代碼。

暫無
暫無

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

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