利用程式具有區段的能力,我們可以將 [如果 A 成立就做 B]
轉換成 [如果 A 不成立就離開]
,用這個方式做邏輯反相可以讓原本看似複雜的程式簡化很多,讓程式變得清晰思慮也會變的清晰,困難的問題就變得簡單,或著就不在是問題了。
這是一段重構前的程式:
foreach (var item in list) { Guid guid = new Guid(item.project_GUID.Value.ToString()); var project = _dc.Project.FirstOrDefault(w => w.ProjectID == guid); if (project != null) { var mails = !String.IsNullOrEmpty(project.AlertEmail) ? project.AlertEmail.Split(new char[]{';'}) : null; if (mails != null) { if(!mails.Any(x => x.mail == "a@b.c")) { foreach (var mail in mails) { if (!mailDic.ContainsKey(mail.Trim())) mailDic.Add(mail, new List<int>()); mailDic[mail].Add(item.projectID); } } } } }
將邏輯反相重構後的程式:
foreach (var item in list) { Guid guid = new Guid(item.project_GUID.Value.ToString()); var project = _dc.Project.FirstOrDefault(w => w.ProjectID == guid); if (project == null) { continue; } if (String.IsNullOrEmpty(project.AlertEmail)) { continue; } var mails = project.AlertEmail.Split(new char[]{';'}); if(mails.Any(x => x.mail == "a@b.c")){ continue; } foreach (var mail in mails) { if (!mailDic.ContainsKey(mail.Trim())) { mailDic.Add(mail, new List<int>()); } mailDic[mail].Add(item.projectID); } }
可以看出程式的縮排階層減少了,也簡化了程式的複雜度,重構的方法就是將 if 反相將 else 前移,也許一開始很難用這種方式寫程式,但是人腦是可以訓練的,在每次重構時進行調整改寫,習慣這種模式後很自然就會用這種[跳離]的思維去寫程式邏輯了。
當然這種方式也是有缺點的,就是有時候不這麼直覺會不好理解,但是可以增加一些註解來輔助描述,或是拆分判斷條件例如:
if (a != null || b == null) { return; } /* 這可以拆分成兩行,不用拘泥一行完成 */ if (a != null) { return; } if (b == null) { return; }
程式邏輯有一個有趣的事,往往用正向邏輯無法處理的問題,改用反相邏輯就會簡單很多,例如:需要用特定的邏輯尋找符合的項目,可能因為那個特定邏輯讓效能非常的差,這時候如果改用不符合特定邏輯的項目排除,留下來的就會是符合的項目,因為是用消去法所以要尋找的數量會越算越少,所以執行效能會收斂。
0 回應:
張貼留言