0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SwiftでTDD写経 第9章 歩幅の調整

Last updated at Posted at 2023-03-19

通貨(Currency)の概念を導入する。

①MoneyクラスにCurrencyの抽象Method入れる。
②やっぱ親クラスにプロパティ入れよ。
③コンストラクタでCurrencyの値入れよ。
④timesMethodは自分のコンストラクタ呼び出すんじゃなくてファクトリメソッド使おう!

playground.swift
import UIKit

var moneytest = MoneyTest()

moneytest.TestMultiplication()
moneytest.TestEquality()
moneytest.TestFrancMultiplication()

class MoneyTest{
    init(){}

    func TestMultiplication(){
        var five:Money = Money.dollar(5)
        assert(Money.dollar(10) == five.times(2))
        assert(Money.dollar(15) == five.times(3))
    }

    func TestEquality(){
        assert(Money.dollar(5) == Money.dollar(5))
        assert(Money.dollar(6) == Money.dollar(6))
        assert(Money.franc(5) == Money.franc(5))
        assert(Money.franc(6) == Money.franc(6))
        assert(Money.franc(6) != Money.franc(3))
        assert(Money.franc(6) != Money.dollar(6))
    }
    
    func TestFrancMultiplication(){
        var five = Money.franc(5)
        assert(Money.franc(10) == five.times(2))
        assert(Money.franc(15) == five.times(3))
    }
}
///親クラス
class Money :Equatable{
    var amount:Int
    var currency:String

    init(_ amount:Int,_ currency:String){
        self.amount = amount
        self.currency = currency
    }
    
    static func == (lhs: Money, rhs: Money) -> Bool {
        return lhs.amount == rhs.amount && type(of: lhs) == type(of: rhs)
    }

    func currency()-> String{
            return currency
        }
    
    func times(_ multiplire:Int)  -> Money{
        return Money(amount , currency)
    }
    
    static func dollar(_ amount:Int) -> Dollar{
        return Dollar(amount,"USD")
    }
    
    static func franc(_ amount:Int) -> Franc{
        return Franc(amount,"CHF")
    }
    
}

///Dollar子クラス
class Dollar:Money {
    override init(_ amount:Int,_ currency:String){
        super.init(_ :amount , _ :currency)
        self.amount = amount
        self.currency = currency
    }
    override func times(_ multiplire:Int)  -> Dollar{
        return Money.dollar(amount * multiplire)
    }
}


///Franc子クラス
class Franc:Money {
    override init(_ amount:Int, _ currency:String){
        super.init(_ :amount , _ :currency)
        self.amount = amount
        self.currency = currency
    }
    override func times(_ multiplire:Int)  -> Franc{
        return Money.franc(amount * multiplire)
    }
}

振り返り
・大きめの設計変更にのめり込みそうになったので、その前に手前にある小さな変更に着手した。
・差異を呼び出し側(FactoryMethod側)に移動することによって、2つのサブクラスのコンストラクタを近づけていった。
・リファクタリングの途中で少し寄り道して、timesメソッドの中でFactoryMethodを使うように変更した。
・Francに行ったリファクタリングをDollarにも同様に、今度は大きい歩幅で一気に適用した。
・完全に同じ内容になった2つのコンストラクタを親クラスに引き上げた。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?