2021-10-16 11:51

重構基礎-邏輯反相

利用程式具有區段的能力,我們可以將 [如果 A 成立就做 B] 轉換成 [如果 A 不成立就離開],用這個方式做邏輯反相可以讓原本看似複雜的程式簡化很多,讓程式變得清晰思慮也會變的清晰,困難的問題就變得簡單,或著就不在是問題了。

這是一段重構前的程式:

  1. foreach (var item in list) 
  2. { 
  3.    Guid guid = new Guid(item.project_GUID.Value.ToString()); 
  4.    var project = _dc.Project.FirstOrDefault(w => w.ProjectID == guid); 
  5.    if (project != null) 
  6.    { 
  7.        var mails = !String.IsNullOrEmpty(project.AlertEmail) ? project.AlertEmail.Split(new char[]{';'}) : null; 
  8.        if (mails != null) 
  9.        { 
  10.            if(!mails.Any(x => x.mail == "a@b.c")) 
  11.            { 
  12.                foreach (var mail in mails) 
  13.                { 
  14.                    if (!mailDic.ContainsKey(mail.Trim())) 
  15.                        mailDic.Add(mail, new List<int>()); 
  16.  
  17.                    mailDic[mail].Add(item.projectID); 
  18.                } 
  19.  
  20.            } 
  21.        } 
  22.    } 
  23. } 

將邏輯反相重構後的程式:

  1. foreach (var item in list) 
  2. { 
  3.    Guid guid = new Guid(item.project_GUID.Value.ToString()); 
  4.    var project = _dc.Project.FirstOrDefault(w => w.ProjectID == guid); 
  5.    if (project == null) { continue; } 
  6.  
  7.    if (String.IsNullOrEmpty(project.AlertEmail)) { continue; } 
  8.  
  9.    var mails = project.AlertEmail.Split(new char[]{';'}); 
  10.    if(mails.Any(x => x.mail == "a@b.c")){ continue; } 
  11.  
  12.    foreach (var mail in mails) 
  13.    { 
  14.        if (!mailDic.ContainsKey(mail.Trim())) 
  15.        { mailDic.Add(mail, new List<int>()); } 
  16.  
  17.        mailDic[mail].Add(item.projectID); 
  18.    } 
  19. } 

可以看出程式的縮排階層減少了,也簡化了程式的複雜度,重構的方法就是將 if 反相將 else 前移,也許一開始很難用這種方式寫程式,但是人腦是可以訓練的,在每次重構時進行調整改寫,習慣這種模式後很自然就會用這種[跳離]的思維去寫程式邏輯了。

當然這種方式也是有缺點的,就是有時候不這麼直覺會不好理解,但是可以增加一些註解來輔助描述,或是拆分判斷條件例如:

  1. if (a != null || b == null) { return; } 
  2.  
  3. /* 這可以拆分成兩行,不用拘泥一行完成 */ 
  4.  
  5. if (a != null) { return; } 
  6. if (b == null) { return; } 

程式邏輯有一個有趣的事,往往用正向邏輯無法處理的問題,改用反相邏輯就會簡單很多,例如:需要用特定的邏輯尋找符合的項目,可能因為那個特定邏輯讓效能非常的差,這時候如果改用不符合特定邏輯的項目排除,留下來的就會是符合的項目,因為是用消去法所以要尋找的數量會越算越少,所以執行效能會收斂。

0 回應: