「リファクタリング 第2版」Swiftでコーディング その14

リファクタリング 第2版

18-20頁 第1章 ボリューム特典ポイント集計箇所の削除 「ループの分離(p.236)」「ステートメントのスライド(p.231)」「問い合わせによる一時変数の置き換え(p.185)」「関数の抽出(p.112)」

Swift版 main.swift

データ生成、結果表示付き。

import Foundation

makeData()

func playFor(aPerformance:Performance) -> Play {
    return plays[aPerformance.playID]!
}

func volumeCreditsFor(aPerformance:Performance) -> Int {
    var result = 0
    result += max(aPerformance.audience - 30, 0)
    if "comedy" == playFor(aPerformance: aPerformance).type {
        result += Int(aPerformance.audience / 5)
    }
    return result
}

func usd(aNumber:Int) -> String {
    let format = NumberFormatter()
    format.numberStyle = .currency
    format.locale = Locale(identifier: "en_US")
    return format.string(from: NSNumber(value: aNumber) / 100)!
}

func totalVolumeCredits(invoice:Invoice) -> Int {
    var volumeCredits = 0
    for perf in invoice.performances {
        volumeCredits += volumeCreditsFor(aPerformance: perf)
    }
    return volumeCredits
}

func statement(invoice:Invoice, plays:Dictionary<String, Play>) -> String {
    var totalAmount = 0
    var result = "Statement for \(invoice.customer)\n"

    for perf in invoice.performances {
        result += "  \(playFor(aPerformance: perf).name): " + usd(aNumber: amountFor(aPerformance: perf)) + " (\(perf.audience) seats)\n"
        totalAmount += amountFor(aPerformance: perf)
    }

    result += "Amount owed is " + usd(aNumber: totalAmount) + "\n"
    result += "You earned \(totalVolumeCredits(invoice: invoice)) credits\n"
    return result
}

func amountFor(aPerformance:Performance) -> Int {
    var result = 0

    switch playFor(aPerformance: aPerformance).type {
    case "tragedy":
        result = 40000
        if aPerformance.audience > 30 {
            result += 1000 * (aPerformance.audience - 30)
        }
    case "comedy":
        result = 30000
        if aPerformance.audience > 20 {
            result += 10000 + 500 * (aPerformance.audience - 20)
        }
        result += 300 * aPerformance.audience
    default:
        print("error")
    }
    return result
}
 
let result = statement(invoice: invoices[0], plays: plays)
print(result)

Swift

Posted by shi-n