2009-05-07 15:43:21
摘要:Switch to Strategy:策略模式转换switch分支
switch 语句块很大,并且会随时引入新的判断条件。这时,最好使用策略模式将每个条件封装到单独的类中。
实现策略模式的方式是很多的。我在这里介绍的策略重构使用的是字典策略,这么做的好处是调用者不必修改原来的代码。
public class ClientCode
{
public decimal CalculateShipping()
{
ShippingInfo shippingInfo = new ShippingInfo();
return shippingInfo.CalculateShippingAmount(State.Alaska);
}
}
public enum State
{
Alaska,
NewYork,
Florida
}
public class ShippingInfo
{
public decimal CalculateShippingAmount(State shipToState)
{
switch (shipToState)
{
case State.Alaska:
return GetAlaskaShippingAmount();
case State.NewYork:
return GetNewYorkShippingAmount();
case State.Florida:
return GetFloridaShippingAmount();
default:
return 0m;
}
}
private decimal GetAlaskaShippingAmount()
{
return 15m;
}
private decimal GetNewYorkShippingAmount()
{
return 10m;
}
private decimal GetFloridaShippingAmount()
{
return 3m;
}
}
要应用该重构,需将每个测试条件至于单独的类中,这些类实现了一个共同的接口。然后将枚举作为字典的键,这样就可以获取正确的实现,并执行其代码了。以后如果希望添加新的条件,只需添加新的实现类,并将其添……
阅读全文
2009-05-06 13:22:28
摘要:Inline Method:将方法内联化
一个方法,其本体如果比其名称更清楚易懂。在方法调用点插入方法本体,然后移除该方法
int GetRating()
{
return (MoreThanFiveLateDeliveries()) ? 2 : 1;
}
bool MoreThanFiveLateDeliveries()
{
return _numberOfLateDeliveries 5;
}
你会发现通过下面重构合并上面的两个方法代码会更具可读性:
int GetRating()
{
return (_numberOfLateDeliveries 5) ? 2 : 1;
}
有时候你会遇到某个方法,其内部代码和方法名称同样清晰易懂。你就可以去掉这个方法,直接使用其中的代码。间接性可能带来帮助,但非必须的间接性总是让人不舒服。
阅读全文
2009-05-05 15:50:24
摘要:Extract Method:提炼方法
你有一段代码可以被组织在一起并独立出来,将这段代码放进一个独立方法中,并让方法名称解释该方法的用途。
public class Receipt
{
private IListdecimal Discounts { get; set; }
private IListdecimal ItemTotals { get; set; }
public decimal CalculateGrandTotal()
{
decimal subTotal = 0m;
foreach (decimal itemTotal in ItemTotals)
subTotal += itemTotal;
if (Discounts.Count 0)
{
foreach (decimal discount in Discounts)
subTotal -= discount;
}
decimal tax = subTotal * 0.065m;
subTotal += tax;
return subTotal;
}
}
你会发现CalculateGrandTotal函数一共做了3件不同的事情:计算总额、折扣和发票税额。开发者为了搞清楚每个功能如何处理而不得不将代码从头看到尾。相比于此,向下面的代码那样将每个任务分解成单独的函数则要节省更多时间,也更具可读性:
public class Receipt
{
private IListdecimal Discounts { get; set; }
private IListdecimal ItemTotals { get; set; }
public decimal CalculateGrandTotal()
{
decimal subTotal = CalculateSubTotal();
subTotal = CalculateDiscounts(subTotal);
subTotal = CalculateTax(subTotal);……
阅读全文