ClassからStructに変更すると、プロパティを変更するメソッドにはmutatingキーワードをつけなければいけない。参考にしている発表では、これが格好悪いのでつける必要がない方法を選択したい。それが関数型プログラミング。SwiftではCopy-On-Writeに実装されていものがあるので、コストを気にしなくてもという事のようだ。
struct Deck {
public func nextCard() -> Card {
let card = Card()
return card
}
}
struct Hand {
private let deck = Deck()
private var cards = [Card]()
public init(deck: Deck, cards: [Card]) {
self.deck = deck
self.cards = cards
}
}
Handのプロパティcardsにカードを追加する場合、プロパティに変更を加えるメソッドを用意するのではなくて、内容をコピーして、カードを追加されたハンドを生成して返す。それとハンドを差し替えればいいじゃないの、という考えだ。
private func insertCard(card: Card, at index: Int) -> Hand {
var mutableCards = cards
mutableCards.insert(card, at: index)
return Hand(deck: deck, cards: mutableCards)
}
これを利用すれば、新規カードの追加はこうなる。
public func addNewCard(at index: Int) -> Hand {
return insertCard(card: deck.nextCard(), at: index)
}
カードの削除はこうだ。
public func deleteCard(at index: Int) -> Hand {
var mutableCards = cards
mutableCards.remove(at: index)
return Hand(deck: deck, cards: mutableCards)
}
これらを組み合わせれば、カードの移動もこうなる。
public func moveCard(fromIndex: Int, toIndex: Int) -> Hand {
return deleteCard(at: fromIndex).insertCard(card: cards[fromIndex], at: toIndex)
}
単なる配列操作だが、美しさを取るか!君はどっちだ!
ソースコード
GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/Hand - GitHub
関連情報
文化を調和させる
【Cocoa練習帳】
http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)