Spiga

一天一个重构方法(13):删除箭头反模式

2009-06-04 06:01:51

Remove Arrowhead Antipattern:删除箭头反模式

简单地说,当你使用大量的嵌套条件判断时,形成了箭头型的代码,这就是箭头反模式(arrowheadantipattern)。我经常在不同的代码库中看到这种现象,这提高了代码的圈复杂度(cyclomatic complexity)。下面的例子演示了箭头反模式:

public class Security
{
	public ISecurityChecker SecurityChecker { get; set; }
	public Security(ISecurityChecker securityChecker)
	{
		SecurityChecker = securityChecker;
	}
	public bool HasAccess(User user, Permission permission, IEnumerable<Permission> exemptions)
	{
		bool hasPermission = false;
		if (user != null)
		{
			if (permission != null)
			{
				if (exemptions.Count() == 0)
				{
					if (SecurityChecker.CheckPermission(user, permission) ||
					exemptions.Contains(permission))
					{
						hasPermission = true;
					}
				}
			}
		}
		return hasPermission;
	}
}

移除箭头反模式的重构和封装条件判断一样简单。这种方式的重构在方法执行之前往往会评估各个条件,下面是重构之后的代码:

public class Security
{
	public ISecurityChecker SecurityChecker { get; set; }
	public Security(ISecurityChecker securityChecker)
	{
		SecurityChecker = securityChecker;
	}
	public bool HasAccess(User user, Permission permission, IEnumerable<Permission> exemptions)
	{
		if (user == null || permission == null)
			return false;
		if (exemptions.Contains(permission))
			return true;
		return SecurityChecker.CheckPermission(user, permission);
	}
}

如你所见,该方法大大整价了可读性和以后的可维护性。不难看出,该方法的所有可能的路径都会经过验证。