go代码演示:重构 改善既有代码的设计(第2版)起点

这是书本的原代码,翻译成的go版本

util/math.go

package util

func Max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

theatre.go

type Play struct {
    Name string
    Type string
}

type Plays map[string]Play

type Performance struct {
    PlayID   string
    Audience int
}

type Invoices struct {
    Customer     string
    Performances []Performance
}

func statement(invoices Invoices, plays Plays) (result string) {
    result = fmt.Sprintf("Statement for %s\n", invoices.Customer)

    var volumeCredits int
    var totalAmount int
    for _, perf := range invoices.Performances {
        play := plays[perf.PlayID]
        var thisAmount int
        switch play.Type {
        case "tragedy":
            thisAmount = 40000
            if perf.Audience > 30 {
                thisAmount += 1000 * (perf.Audience - 30)
            }
            break
        case "comedy":
            thisAmount = 30000
            if perf.Audience > 20 {
                thisAmount += 10000 + 500*(perf.Audience-20)
            }
            thisAmount += 300 * perf.Audience
            break
        default:
            panic(fmt.Sprintf("unknow type: %s", play.Type))
        }

        volumeCredits += util.Max(perf.Audience-30, 0)
        if play.Type == "comedy" {
            volumeCredits += perf.Audience / 5
        }

        result += fmt.Sprintf("    %s: %d(%d seats)\n", play.Name, thisAmount/100, perf.Audience)
        totalAmount += thisAmount
    }

    result += fmt.Sprintf("Amount Owed is %d\n", totalAmount/100)
    result += fmt.Sprintf("You earned %d credits\n", volumeCredits)
    return result
}

theatre_test.go

type StatementTest struct {
    plays    Plays
    invoices Invoices
    expect   string
}

var _example1 = StatementTest{
    plays: Plays{
        "hamlet":  {Name: "Hamlet", Type: "tragedy"},
        "as-like": {Name: "As You Like It", Type: "comedy"},
        "othello": {Name: "Othello", Type: "tragedy"},
    },
    invoices: Invoices{
        Customer: "BigCo",
        Performances: []Performance{
            {PlayID: "hamlet", Audience: 55},
            {PlayID: "as-like", Audience: 35},
            {PlayID: "othello", Audience: 40},
        },
    },
    expect: "Statement for BigCo\n    Hamlet: 650(55 seats)\n    As You Like It: 580(35 seats)\n    Othello: 500(40 seats)\nAmount Owed is 1730\nYou earned 47 credits\n",
}

func TestStatement(t *testing.T) {
    Convey("example1", t, func() {
        actual := statement(_example1.invoices, _example1.plays)
        So(actual, ShouldEqual, _example1.expect)
    })
}

你可能感兴趣的:(go代码演示:重构 改善既有代码的设计(第2版)起点)