《重构》10. 简化条件逻辑
🏷️ 《重构》
10.1 分解条件表达式(Decompose Conditional)
本手法其实只是提炼函数(Extract Function)的一个应用场景。
重构前:
csharp
if (aDate >= plan.SummerStart && aDate <= plan.SummerEnd)
{
charge = quantity * plan.SummerRate;
}
else
{
charge = quantity * plan.RegularRate + plan.RegularServiceCharge;
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
重构后:
csharp
if (IsSummer())
{
charge = SummerCharge();
}
else
{
charge = RegulargeCharge();
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
10.2 合并条件表达式(Consolidate Conditional Expression)
重构前:
csharp
if (anEmployee.Seniority < 2) return 0;
if (anEmployee.MonthsDisabled > 12) return 0;
if (anEmployee.IsPartTime) return 0;
1
2
3
2
3
重构后:
csharp
if (IsNotEligibleForDisability()) return 0;
bool IsNotEligibleForDisability()
{
return anEmployee.Seniority < 2 || anEmployee.MonthsDisabled > 12 || anEmployee.IsPartTime;
}
1
2
3
4
5
6
2
3
4
5
6
10.3 以卫语句取代嵌套条件表达式(Replace Nested Conditional with Guard Clauses)
重构前:
csharp
int result;
if (isDead)
{
result = DeadAmount();
}
else
{
if (isSeparated)
{
result = SeparatedAmount();
}
else
{
if (isRetired)
{
result = RediredAmount();
}
else
{
result = NormalAmount();
}
}
}
return result;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
重构后:
csharp
if (isDead) return DeadAmount();
if (isSeparated) return SeparatedAmount();
if (isRetired) return RediredAmount();
return NormalAmount();
1
2
3
4
2
3
4
10.4 以多态取代条件表达式(Replace Conditional with Polymorphism)
多态是面向对象编程的关键特性之一。
重构前:
csharp
switch (bird.Type)
{
case "EuropeanSwallow":
return "average";
case "AfricanSwallow":
return bird.NumberOfCoconuts > 2 ? "tired" : "average";
case "NorwegianBlueParrot":
return bird.Voltage > 100 ? "scorched" : "beautiful";
default:
return "unknown";
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
重构后:
csharp
private class Bird
{
public string Type { get; internal set; }
public int NumberOfCoconuts { get; internal set; }
public int Voltage { get; internal set; }
public virtual string Plumage => "unknown";
}
private class EuropeanSwallow : Bird
{
public override string Plumage => "average";
}
private class AfricanSwallow : Bird
{
public override string Plumage => NumberOfCoconuts > 2 ? "tired" : "average";
}
private class NorwegianBlueParrot : Bird
{
public override string Plumage => Voltage > 100 ? "scorched" : "beautiful";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
10.5 引入特例(Introduce Special Case)
曾用名:引入 NULL 对象(Introduce Null Object)
重构前:
csharp
if ("unknown".Equals(aCustomer)) customerName = "occupant";
1
重构后:
csharp
class UnknownCustomer : Customer
{
public override string Name => "occupant";
}
1
2
3
4
2
3
4
10.6 引入断言(Introduce Assertion)
C# 中貌似没法直接在处理中引入断言,只能通过测试类来实现类似功能。
下面的示例使用的是 JavaScript 语言,其中的断言 assert 方法是单独的插件提供的。
断言是一个条件表达式,应该总是为真。如果它失败,表示程序员犯了错误。断言的失败不应该被系统任何地方捕捉。
重构前:
csharp
if (this.discountRate)
base = base - (this.discountRate * base);
1
2
2
重构后:
csharp
assert(this.discountRate >= 0);
if (this.discountRate)
base = base - (this.discountRate * base);
1
2
3
2
3
附 1. 引用
- 《重构:改善既有代码的设计》 -- 马丁·福勒(Martin Fowler)