IMZRH的日志

努力成为一个有用的人

导航

31天重构指南之二十四:分解复杂判断

Posted on 2009-10-16 16:59  张荣华  阅读(683)  评论(1编辑  收藏  举报

今天要说的重构基于c2 wiki上的条目,你可以在这里查看该条目,在这里还有另一篇文章。

简单的来说,当你的代码中有很深的嵌套条件时,花括号就会在代码中形成一个箭头。我经常在不同的代码中看到这种情况,并且这种情况也会引起较高的圈度复杂性。

下面就的代码便是一个例子:

   1: public class Security
   2: {
   3:     public ISecurityChecker SecurityChecker { get; set; }
   4:  
   5:     public Security(ISecurityChecker securityChecker)
   6:     {
   7:         SecurityChecker = securityChecker;
   8:     }
   9:  
  10:     public bool HasAccess(User user, Permission permission, IEnumerable<Permission> exemptions)
  11:     {
  12:         bool hasPermission = false;
  13:  
  14:         if (user != null)
  15:         {
  16:             if (permission != null)
  17:             {
  18:                 if (exemptions.Count() == 0)
  19:                 {
  20:                     if (SecurityChecker.CheckPermission(user, permission) || exemptions.Contains(permission))
  21:                     {
  22:                         hasPermission = true;
  23:                     }
  24:                 }
  25:             }
  26:         }
  27:  
  28:         return hasPermission;
  29:     }
  30: }
 
重构上面的代码也很简单,如果有可能尽量将条件从方法中移除,我们让代码在做处理任务之前先检查条件,这有些基于约定编程的味道。下面是重构后的代码:
 
   1: public class Security
   2: {
   3:     public ISecurityChecker SecurityChecker { get; set; }
   4:  
   5:     public Security(ISecurityChecker securityChecker)
   6:     {
   7:         SecurityChecker = securityChecker;
   8:     }
   9:  
  10:     public bool HasAccess(User user, Permission permission, IEnumerable<Permission> exemptions)
  11:     {
  12:         if (user == null || permission == null)
  13:             return false;
  14:  
  15:         if (exemptions.Contains(permission))
  16:             return true;
  17:  
  18:         return SecurityChecker.CheckPermission(user, permission);
  19:     }
  20: }
 
如你所看到的,重构后的代码可读性和可维护性更好了,我们读代码时遍历程序的所有分支路径也变得简单起来了。
原文链接:http://www.lostechies.com/blogs/sean_chambers/archive/2009/08/24/refactoring-day-24-remove-arrowhead-antipattern.aspx