Skip to content

《重构》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;
}

重构后

csharp
if (IsSummer())
{
    charge = SummerCharge();
}
else
{
    charge = RegulargeCharge();
}

10.2 合并条件表达式(Consolidate Conditional Expression)

重构前

csharp
if (anEmployee.Seniority < 2) return 0;
if (anEmployee.MonthsDisabled > 12) return 0;
if (anEmployee.IsPartTime) return 0;

重构后

csharp
if (IsNotEligibleForDisability()) return 0;

bool IsNotEligibleForDisability()
{
    return anEmployee.Seniority < 2 || anEmployee.MonthsDisabled > 12 || anEmployee.IsPartTime;
}

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;

重构后

csharp
if (isDead) return DeadAmount();
if (isSeparated) return SeparatedAmount();
if (isRetired) return RediredAmount();
return NormalAmount();

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";
}

重构后

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";
}

10.5 引入特例(Introduce Special Case)

曾用名引入 NULL 对象(Introduce Null Object)

重构前

csharp
if ("unknown".Equals(aCustomer)) customerName = "occupant";

重构后

csharp
class UnknownCustomer : Customer
{
    public override string Name => "occupant";
}

10.6 引入断言(Introduce Assertion)

C# 中貌似没法直接在处理中引入断言,只能通过测试类来实现类似功能。

下面的示例使用的是 JavaScript 语言,其中的断言 assert 方法是单独的插件提供的。

断言是一个条件表达式,应该总是为真。如果它失败,表示程序员犯了错误。断言的失败不应该被系统任何地方捕捉。

重构前

csharp
if (this.discountRate)
    base = base - (this.discountRate * base);

重构后

csharp
assert(this.discountRate >= 0);
if (this.discountRate)
    base = base - (this.discountRate * base);

附 1. 引用

  1. 《重构:改善既有代码的设计》 -- 马丁·福勒(Martin Fowler

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.