重构手法之简化条件表达式【2】
本小节目录
3Consolidate Duplicate Conditional Fragments(合并重复的条件片段)
概要
在条件表达式的每个分支上有着相同的一段代码。
将这段重复代码搬到条件表达式之外。
动机
如果有一组条件表达式的所有分支都执行了相同的某段代码,将这段代码搬移到条件表达式外面。这样才能更清楚地表明哪些东西随条件的变化而变化、哪些东西保持不变。
范例
假如有如下代码:
class Deal { public double Price { get; set; } private bool IsSpecialDeal() { //your code here return true; } private void Send() { //your code here } public double GetTotalPrice() { double total; if (IsSpecialDeal()) { total = Price * 0.95; Send(); } else { total = Price * 0.98; Send(); } return total; } }
由于条件表达式的两个分支都执行了Send()函数,所以将其移到条件表达式的外围:
class Deal { public double Price { get; set; } private bool IsSpecialDeal() { //your code here return true; } private void Send() { //your code here } public double GetTotalPrice() { double total; if (IsSpecialDeal()) { total = Price * 0.95; } else { total = Price * 0.98; } Send(); return total; } }
这样的重构手法同时也可以避免重复代码。
小结
我们在对待异常时,也是这样做的。如果try块和catch块内都重复执行了同一段代码,可以将其移到finally块内。
4Remove Control Flag(移除控制标记)
概要
在一系列布尔表达式中,某个变量带着“控制标记”(control flag)的作用。
以break语句或return语句取代控制标记。
动机
在一系列条件表达式中,常常会看到用以判断何时停止条件检查的控制标记:
set done to false
while not done
if(condition)
do something
set done to true
next step of loop
这样的控制标记大大降低了条件表达式的可读性。以break语句或return语句取代控制标记,会带来很大的便利。
范例:以break取代简单的控制标记
下列函数用来检查一系列人名之中是否包含两个可疑人物的名字:
class Person { public void CheckSecurity(string[] people) { bool found = false; foreach (var person in people) { if (!found) { if (person == "Don") { SendAlert(); found = true; } if (person == "John") { SendAlert(); found = true; } } } } private void SendAlert() { } }
这种情况下很容易找出控制标记:当变量found被赋予true时,搜索就结束。这样我们可以引入break语句替换掉对found变量赋值的语句,替换完成后删除控制标记的引用:
class Person { public void CheckSecurity(string[] people) { foreach (var person in people) { if (person == "Don") { SendAlert(); break; } if (person == "John") { SendAlert(); break; } } } private void SendAlert() { } }
范例:以return返回控制标记
我们将上面的例子稍微改动下:
class Person { public void CheckSecurity(string[] people) { string found = string.Empty; foreach (var person in people) { if (found == string.Empty) { if (person == "Don") { SendAlert(); found = "Don"; } if (person == "John") { SendAlert(); found = "John"; } } } OtherMethod(found); } private void SendAlert() { } private void OtherMethod(string found) { } }
在这里,变量found做了两件事:既是控制标记,也是运算结果。遇到这种情况,一般都是先把计算found变量的代码提炼到一个独立函数中:
class Person { public void CheckSecurity(string[] people) { string found = FoundMiscreant(people); OtherMethod(found); } private string FoundMiscreant(string[] people) { string found = string.Empty; foreach (var person in people) { if (person == "Don") { SendAlert(); found = "Don"; } if (person == "John") { SendAlert(); found = "John"; } } return found; } private void SendAlert() { } private void OtherMethod(string found) { } }
然后以return语句取代控制语句,并且完全去掉控制标记:
class Person { public void CheckSecurity(string[] people) { string found = FoundMiscreant(people); OtherMethod(found); } private string FoundMiscreant(string[] people) { foreach (var person in people) { if (person == "Don") { SendAlert(); return "Don"; } if (person == "John") { SendAlert(); return "John"; } } return string.Empty; } private void SendAlert() { } private void OtherMethod(string found) { } }
如果返回值是void,也可以用return语句取代控制标记,只不过是一个空的return。
小结
如果以此办法去处理带有副作用的函数,需要先将查询函数和修改函数分离。
To Be Continued……
- 重构手法之简化条件表达式【4】
- 重构手法之简化条件表达式【1】
- 重构手法(三)之简化条件表达式
- 重构手法之简化条件表达式【3】
- 【重构笔记】重构手法之简化条件表达式
- 重构改善既有代码的设计:简化条件表达式
- 《重构改善既有代码的设计》之重构列表--简化条件表达式(一)
- 【重构笔记05】简化条件表达式
- 重构——简化条件表达式9.5
- 重构-改善既有代码的设计:简化条件表达式(七)
- 重构之简化条件表达式
- 重构手法35:Consolidate Conditional Expression (合并条件表达式)
- 重构系列之对象行为的重构:《重构》简化条件表达式
- 重构摘要9_简化条件表达式
- 重构代码-简化条件表达式
- 重构改善既有代码的设计--简化条件表达式
- 《重构--改善既有代码的设计》--简化条件表达式(9)
- 代码重构---简化条件表达式
- PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式【链接:http://www.cnblogs.com/baochuan/archive/2012/04/06/2432478.html】