●timesが似ているので統一してしまいたい。
→返すオブジェクトの型をMoney型にしてしまおう
playground.swift
///Dollar子クラス
class Dollar:Money {
override init(_ amount:Int){
super.init(_ :amount)
self.amount = amount
}
func times(_ multiplire:Int) -> Money{
return Dollar(amount * multiplire)
}
}
///Franc子クラス
class Franc:Money {
override init(_ amount:Int){
super.init(_ :amount)
self.amount = amount
}
func times(_ multiplire:Int) -> Franc({
return Franc(amount * multiplire)
}
}
●サブクラスのDollarとFrancは大した仕事してないから消してしまおう。
→ちょっと複雑だから小さく変更していく。子クラスの参照から消し去る。
ここでfactory Methodを適用するぜ!
(要はMoneyクラスが工場で、DollarやFrancはその工場から作られるアンパンマンの頭だ!(パンな))
playground.swift
class MoneyTest{
init(){}
func TestMultiplication(){
var five = Money.Dollar(5)
assert(Dollar(10) == five.times(2))
assert(Dollar(15) == five.times(3))
}
func TestFrancMultiplication(){
var five = Money.Franc(5)
assert(Franc(10) == five.times(2))
assert(Franc(15) == five.times(3))
}
}
playground.swift
///親クラス
class Money :Equatable{
var amount:Int
init(_ amount:Int){
self.amount = amount
}
static func == (lhs: Money, rhs: Money) -> Bool {
return lhs.amount == rhs.amount && type(of: lhs) == type(of: rhs)
}
static func dollar(_ amount:Int) -> Dollar{
return Dollar(amount)
}
}
Javaでいうabstractが、swiftではprotocolを使えば表現できるんですが今回は見送り。
(Swiftは抽象クラスをサポートしてません。)
playground.swift
import UIKit
var moneytest = MoneyTest()
moneytest.TestMultiplication()
moneytest.TestEquality()
moneytest.TestFrancMultiplication()
class MoneyTest{
init(){}
func TestMultiplication(){
var five: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 = Franc(5)
assert(Money.franc(10) == five.times(2))
assert(Money.franc(15) == five.times(3))
}
}
///親クラス
class Money :Equatable{
var amount:Int
init(_ amount:Int){
self.amount = amount
}
static func == (lhs: Money, rhs: Money) -> Bool {
return lhs.amount == rhs.amount && type(of: lhs) == type(of: rhs)
}
func times(_ multiplire:Int) -> Money{
return Money(amount * multiplire)
}
static func dollar(_ amount:Int) -> Dollar{
return Dollar(amount)
}
static func franc(_ amount:Int) -> Franc{
return Franc(amount)
}
}
///Dollar子クラス
class Dollar:Money {
override init(_ amount:Int){
super.init(_ :amount)
self.amount = amount
}
override func times(_ multiplire:Int) -> Money{
return Dollar(amount * multiplire)
}
}
///Franc子クラス
class Franc:Money {
override init(_ amount:Int){
super.init(_ :amount)
self.amount = amount
}
override func times(_ multiplire:Int) -> Money{
return Franc(amount * multiplire)
}
}