第2天:有人告诉我将没有数学(奖金)
#教程 #tdd #go #adventofcode

你好体育迷!

如前所述,我们今天回到了一个很小的重构,同时解决了Day 2: I Was Told There Would Be No Math (Part 2)

此重构的原因是减少代码的重复。得益于测试驱动的开发,这将变得很好,很容易。

所以让我们查看我们的重复代码。

示例1:

func CalculatePresentArea(str string) int {
    s := strings.Split(str, "x")

    var sides []int
    for _, sideString := range s {
        side, _ := strconv.Atoi(sideString)
        sides = append(sides, side)
    }

    sort.Ints(sides)

    return sides[0]*sides[1]*3 + sides[0]*sides[2]*2 + sides[1]*sides[2]*2
}

示例2:

func CalculateRibbonLength(str string) int {
    s := strings.Split(str, "x")

    var sides []int
    for _, sideString := range s {
        side, _ := strconv.Atoi(sideString)
        sides = append(sides, side)
    }

    sort.Ints(sides)

    return sides[0] + sides[0] + sides[1] + sides[1] + sides[0]*sides[1]*sides[2]
}

正如我们所看到的,这两个函数的大部分都是完全相同的。

因此,让我们为一个函数编写测试,我们可以用来使此过程干燥。

func TestMakeSortedIntSlice(t *testing.T) {
    assert.Equal(t, []int{5, 13, 19}, MakeSortedIntSlice([]string{"13x5x19"}))
    assert.Equal(t, []int{22, 26, 28}, MakeSortedIntSlice([]string{"22x28x26"}))
    assert.Equal(t, []int{12, 26, 29}, MakeSortedIntSlice([]string{"29x26x12"}))
    assert.Equal(t, []int{4, 7, 17}, MakeSortedIntSlice([]string{"4x7x17"}))
    assert.Equal(t, []int{14, 30, 30}, MakeSortedIntSlice([]string{"30x30x14"}))
}

我们知道,此时运行go test将产生以下失败:

# github.com/damiensedgwick/aoc2015/day_2 [github.com/damiensedgwick/aoc2015/day_2.test]
./main_test.go:28:36: undefined: MakeSortedIntSlice
./main_test.go:29:37: undefined: MakeSortedIntSlice
./main_test.go:30:37: undefined: MakeSortedIntSlice
./main_test.go:31:35: undefined: MakeSortedIntSlice
./main_test.go:32:37: undefined: MakeSortedIntSlice
FAIL    github.com/damiensedgwick/aoc2015/day_2 [build failed]

所以让我们写下我们的功能并获得此测试。

func MakeSortedIntSlice(str string) []int {
    s := strings.Split(str, "x")

    var sides []int
    for _, sideString := range s {
        side, _ := strconv.Atoi(sideString)
        sides = append(sides, side)
    }

    sort.Ints(sides)

    return sides
}

如果我们再次进行测试,我们将看到它们现在已经过去了,完美。

现在,我们可以在两个较早的示例中替换重复的代码,以便它们现在看起来像这样:

示例1:

func CalculatePresentArea(str string) int {
    s := MakeSortedIntSlice(str)

    return s[0]*s[1]*3 + s[0]*s[2]*2 + s[1]*s[2]*2
}

示例2:

func CalculateRibbonLength(str string) int {
    s := MakeSortedIntSlice(str)

    return s[0] + s[0] + s[1] + s[1] + s[0]*s[1]*s[2]
}

更干净!

尽管这是一个相当简单的例子,但我强烈建议使用测试来重构代码!

下次我们看看第3天,然后见。