Kotlinとスプラトゥーンで学ぶデザインパターン【7. Builder】
休日にやりたいことがありすぎてなかなかブログを更新できてません。
気がついてたら半年ぶりの更新になってた。
スプラトゥーン2は地味に続けてますが最近はNine Parchmentsにはまってます。
Builder パターンとは
普段Androidアプリの開発をしているとBuilderパターンで書かれているクラスをよく見ます。
StringBuilderとかOkHttpClientとか。
Builderパターンは複雑な処理を、段階的に組み上げていくパターンです。
また組み上げ方は固定ですが、組み上げる時に使用するオブジェクトは柔軟に変えられるようになってます。
実装
メインとなるクラスはDirectorとBuilderで、この2クラスで組み上げ方を決めています。
Director.kt
class Director(private val builder: MainWeaponBuilder) { fun construct() { builder.name(".96ガロン") builder.power(62) builder.range(31) builder.quickness(10) } }
MainWeaponBuilder.kt
abstract class MainWeaponBuilder { abstract fun name(name: String) abstract fun range(range: Int) abstract fun power(power: Int) abstract fun quickness(quickness: Int) }
今回はスプラトゥーン熱が低かったせいか例があまり良くないですがDirectorクラスは.96ガロンを作成するクラスとなっています。
デコるかどうかは使用するBuilderクラスに寄ります。
無印を作りたい場合はUnmarkedWeaponBuilderを、デコを作りたい場合はDecoratorWeaponBuilderを使用すれば作成できます。
UnmarkedWeaponBuilder.kt
class UnmarkedWeaponBuilder : MainWeaponBuilder() { var name: String? = null var range: Int = 0 var power: Int = 0 var quickness: Int = 0 override fun name(name: String) { this.name = name } override fun range(range: Int) { this.range = range } override fun power(power: Int) { this.power = power } override fun quickness(quickness: Int) { this.quickness = quickness } fun getResult(): Weapon { return Weapon(name!!, range, power, quickness) } }
DecoratorWeaponBuilder.kt
class DecoratorWeaponBuilder : MainWeaponBuilder() { var name: String? = null var range: Int = 0 var power: Int = 0 var quickness: Int = 0 override fun name(name: String) { this.name = "${name}デコ" } override fun range(range: Int) { this.range = range } override fun power(power: Int) { this.power = power } override fun quickness(quickness: Int) { this.quickness = quickness } fun getResult(): Weapon { return Weapon(name!!, range, power, quickness) } }
改めて見ても例がいまいち・・・。
実行結果
それぞれの.96ガロンを作成して見ます。
Main.kt
fun main(args: Array<String>) { val unmarkedBuilder = UnmarkedWeaponBuilder() var director = Director(unmarkedBuilder) director.construct() println(unmarkedBuilder.getResult()) val decoratorBuilder = DecoratorWeaponBuilder() director = Director(decoratorBuilder) director.construct() println(decoratorBuilder.getResult()) }
結果は
Weapon(name=.96ガロン, range=31, power=62, quickness=10) Weapon(name=.96ガロンデコ, range=31, power=62, quickness=10)