Spiga

一天一个重构方法(16):消除双重否定

2009-06-20 01:57:34

Remove Double Negative:删除双重否定

尽管我在很多代码中发现了这种严重降低可读性并往往传达错误意图的坏味道,但这种重构本身还是很容易实现的。这种毁灭性的代码所基于的假设导致了错误的代码编写习惯,并最终导致bug。如下例所示:

public class Order
{
	public void Checkout(IEnumerable<Product> products, Customer customer)
	{
		if (!customer.IsNotFlagged)
		{
			// the customer account is flagged
			// log some errors and return
			return;
		}
		// normal order processing
	}
}
public class Customer
{
	public decimal Balance { get; private set; }
	public bool IsNotFlagged
	{
		get { return Balance < 30m; }
	}
}

如你所见,这里的双重否定十分难以理解,我们不得不找出什么才是双重否定所要表达的肯定状态。修改代码是很容易的。如果我们找不到肯定的判断,可以添加一个处理双重否定的假设,而不要在得到结果之后再去验证。

public class Order
{
	public void Checkout(IEnumerable<Product> products, Customer customer)
	{
		if (customer.IsFlagged)
		{
			// the customer account is flagged
			// log some errors and return
			return;
		}
		// normal order processing
	}
}
public class Customer
{
	public decimal Balance { get; private set; }
	public bool IsFlagged
	{
		get { return Balance >= 30m; }
	}
}