「リファクタリング 第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)