Kotlinとスプラトゥーンで学ぶデザインパターン【6. Prototype】
久しぶりの更新になってしまいました。
スプラトゥーン2が発売されたし仕方ないよね。ちまちま空いてる時間にプレイしてます。
↓今の状況です。
#Splatoon2 #SplatNet2 pic.twitter.com/Rk4OgkqwA3
— kzt (@seiizo) 2017年9月30日
今回はPrototypeパターンです。Singletonパターンをすでにやってるつもりになってとばしてしまった・・・
Prototype パターンとは
インスタンスを作る時、通常は作りたいクラスをnewして作成しますが、
そうではなく既存のインスタンスをコピーして作る。それをPrototypeパターンと呼ぶらしいです。
なぜそのような実装をするかというと
などの理由が挙げられます。
実装
スプラトゥーンからは離れてしまいますが、セーブデータを題材にしてみました。
セーブデータの中にはいろいろな情報が入っており、クラスからインスタンス化するには難しいというか面倒くさいです。
そこでprototypeパターンを使って実装してみます。
SaveData.kt
class SaveData(val user: User, val games: Array<String>) : Cloneable { fun createClone(): SaveData { return clone() as SaveData } fun print() { println("id:" + user.id) println("name:" + user.name) println("registered game datas:") games.forEach { println(it) } } }
SaveDataManager.kt
class SaveDataManager { fun create(user: User, games: Array<String>): SaveData { return SaveData(user, games) } fun copy(data: SaveData):SaveData { return data.createClone() } }
SaveDataにCloneableインターフェースを実装してクローンできるようにしてます。これが今回のキモですね。
cloneは外部に見えないので別途メソッドを作って対応しました。
Main.kt
fun main(args: Array<String>) { val user = User(123, "seito") var games:Array<String> = arrayOf("Splatoon2", "Mario Kart") val manager: SaveDataManager = SaveDataManager() val newSaveData = manager.create(user, games) newSaveData.print() val copiedSaveData = manager.copy(newSaveData) copiedSaveData.print() }
一度セーブデータを作ってそれをコピーして同じ出力結果になるよねーって確認をしています。
実行結果
id:123 name:seito registered game datas: Splatoon2 Mario Kart id:123 name:seito registered game datas: Splatoon2 Mario Kart
感想
デザパタ本を読みながら作ったらManagerクラスができたんですが、今回の場合Manager内で扱うクラスは1種類なのでManagerクラスを作らないでMainから直接createCloneを呼んだほうがすっきりするだろうなーと思ったり。
スケーラビリティを考えるとManagerクラスがあってもいいけどスケールする可能性あるのか。