《重构-改善既有代码设计》案例之C#版(3)

书接上文

在这个Statement方法中金额、积分、结果字符串已经相对统一了。还有一个美元格式化变量格格不入,每次用到它的时候都是string.Format(nfi, "{0:C}", AmountFor(perf) / 100)是不是代码也比较不易于理解。所以想到一个办法,继续提炼这个美元格式化代码

1         private string Usd(int aNumber)
2         {
3             NumberFormatInfo nfi = new CultureInfo("en-US").NumberFormat;
4             nfi.CurrencyDecimalDigits = 2;
5             return string.Format(nfi, "{0:C}", aNumber / 100);
6         }
View Code

这个方法名字Usd可谓精髓,一眼就知道是干啥的

所以Statement就变成这样了(勘误:总金额不用再除100了)

 1         public string Statement()
 2         {
 3             int totalAmount = 0;
 4             int volumeCredits = 0;
 5             string result = $"Statement for {_invoice.Customer} \n";
 6 
 7             foreach (var perf in _invoice.performances)
 8             {
 9                 volumeCredits += VolumeCreditsFor(perf);
10                 //print line for this order
11                 result += $"{PlayFor(perf).name}: {Usd(AmountFor(perf))}({perf.audience}seats)\n";
12                 totalAmount += AmountFor(perf);
13             }
14 
15             result += $"Amount owed is {Usd(totalAmount / 100)}\n";
16             result += $"You earned {volumeCredits} credits \n";
17             return result;
18         }
View Code

 如果是我的话,我最多也就只能想到这里了。。。但是大神就是大神。

现在这个foreach循环里,干了三件事。大神拆成了3个foreach,然后把变量移动,紧挨这使用到他们的地方。(勘误:总金额不用再除100了)

 1         public string Statement()
 2         {
 3             int volumeCredits = 0;
 4             foreach (var perf in _invoice.performances)
 5             {
 6                 volumeCredits += VolumeCreditsFor(perf);
 7             }
 8 
 9             int totalAmount = 0;
10             foreach (var perf in _invoice.performances)
11             {
12                 totalAmount += AmountFor(perf);
13             }
14 
15             string result = $"Statement for {_invoice.Customer} \n";
16             foreach (var perf in _invoice.performances)
17             {
18                 result += $"{PlayFor(perf).name}: {Usd(AmountFor(perf))}({perf.audience}seats)\n";
19             }
20 
21             result += $"Amount owed is {Usd(totalAmount / 100)}\n";
22             result += $"You earned {volumeCredits} credits \n";
23             return result;
24         }
View Code

然后把计算总积分,总金额的代码又提炼了两个方法

 1         private int TotalAmount()
 2         {
 3             int result = 0;
 4             foreach (var perf in _invoice.performances)
 5             {
 6                 result += AmountFor(perf);
 7             }
 8 
 9             return result;
10         }
11 
12         private int TotalVolumeCredits()
13         {
14             int result = 0;
15             foreach (var perf in _invoice.performances)
16             {
17                 result += VolumeCreditsFor(perf);
18             }
19 
20             return result;
21         }
View Code

再使用内联变量的手法 (勘误:总金额不用再除100了)

 1         public string Statement()
 2         {
 3             string result = $"Statement for {_invoice.Customer} \n";
 4             foreach (var perf in _invoice.performances)
 5             {
 6                 result += $"{PlayFor(perf).name}: {Usd(AmountFor(perf))}({perf.audience}seats)\n";
 7             }
 8 
 9             result += $"Amount owed is {Usd(TotalAmount() / 100)}\n";
10             result += $"You earned {TotalVolumeCredits()} credits \n";
11             return result;
12         }
View Code

如此一来Statement只处理结果字符串,计算金额和积分的代码不再搅合在一起了(但仍然使用到了计算金额,积分的方法),只剩下了几行代码

大神下一步的思路就是使得计算阶段和格式化输出阶段分离。

本篇完成...待续....

 上一篇:《重构-改善既有代码设计》案例之C#版(2) 下一篇:《重构-改善既有代码设计》案例之C#版(4)

posted @ 2023-03-11 18:15  吾乃零陵上将军邢道荣  阅读(25)  评论(0编辑  收藏  举报