四畳半の秘密基地

さあ、今日はどんな実験をしよう

MENU

Kotlinとスプラトゥーンで学ぶデザインパターン【6. Prototype】

久しぶりの更新になってしまいました。
スプラトゥーン2が発売されたし仕方ないよね。ちまちま空いてる時間にプレイしてます。
↓今の状況です。

今回は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クラスがあってもいいけどスケールする可能性あるのか。