[解決済み] KotlinでBuilderパターンを実装するには?
質問
こんにちは、Kotlinの世界に入ったばかりの初心者です。私はこれまで見てきたものが好きで、私たちのアプリケーションで使用しているライブラリのいくつかをJavaからKotlinに変換することを考え始めました。
これらのライブラリは、セッター、ゲッター、ビルダークラスを持つPojosでいっぱいです。今、私はKotlinでBuilderを実装する最良の方法は何かを見つけるためにググっていますが、成功しません。
2回目の更新:問題は、Kotlinでいくつかのパラメータを持つ単純なpojoのためのBuilderデザインパターンをどのように書くかです。以下のコードは、Javaのコードを書いてから、eclipse-kotlin-pluginを使ってKotlinに変換してみたものです。
class Car private constructor(builder:Car.Builder) {
var model:String? = null
var year:Int = 0
init {
this.model = builder.model
this.year = builder.year
}
companion object Builder {
var model:String? = null
private set
var year:Int = 0
private set
fun model(model:String):Builder {
this.model = model
return this
}
fun year(year:Int):Builder {
this.year = year
return this
}
fun build():Car {
val car = Car(this)
return car
}
}
}
解決方法は?
まず第一に、Kotlinにはデフォルト引数と名前付き引数があるので、ほとんどの場合、ビルダーを使う必要はありません。これによって、以下のように書くことができます。
class Car(val model: String? = null, val year: Int = 0)
というように使用します。
val car = Car(model = "X")
どうしてもビルダーを使いたい場合は、以下のような方法があります。
ビルダーを
companion object
は意味をなさない。
object
はシングルトンです。代わりにネストしたクラスとして宣言します(Kotlinではデフォルトで静的です)。
プロパティをコンストラクタに移動して、オブジェクトを通常の方法でインスタンス化できるようにし(コンストラクタをプライベートにしておく)、ビルダーを受け取って一次コンストラクタに委譲する二次コンストラクタを使用します。コードは以下のようになります。
class Car( //add private constructor if necessary
val model: String?,
val year: Int
) {
private constructor(builder: Builder) : this(builder.model, builder.year)
class Builder {
var model: String? = null
private set
var year: Int = 0
private set
fun model(model: String) = apply { this.model = model }
fun year(year: Int) = apply { this.year = year }
fun build() = Car(this)
}
}
使用方法
val car = Car.Builder().model("X").build()
このコードは、さらに ビルダーDSL :
class Car (
val model: String?,
val year: Int
) {
private constructor(builder: Builder) : this(builder.model, builder.year)
companion object {
inline fun build(block: Builder.() -> Unit) = Builder().apply(block).build()
}
class Builder {
var model: String? = null
var year: Int = 0
fun build() = Car(this)
}
}
使用方法
val car = Car.build { model = "X" }
いくつかの値が必要で、デフォルト値を持たない場合、ビルダーのコンストラクタにその値を入れる必要があります。
build
メソッドを定義しました。
class Car (
val model: String?,
val year: Int,
val required: String
) {
private constructor(builder: Builder) : this(builder.model, builder.year, builder.required)
companion object {
inline fun build(required: String, block: Builder.() -> Unit) = Builder(required).apply(block).build()
}
class Builder(
val required: String
) {
var model: String? = null
var year: Int = 0
fun build() = Car(this)
}
}
使用方法
val car = Car.build(required = "requiredValue") { model = "X" }
関連
-
[解決済み] 静的クラスとシングルトンパターンの違い?
-
[解決済み] Kotlin 三項条件演算子
-
[解決済み】KotlinでJavaの静的メソッドに相当するものは何ですか?
-
[解決済み】C++ シングルトンデザインパターン
-
[解決済み] コード内のスイッチをなくす方法【非公開
-
[解決済み] Facade、Proxy、Adapter、Decoratorのデザインパターンの違い?
-
[解決済み] リポジトリとサービスの違い?
-
[解決済み] ソーシャルネットワークにアクティビティストリームを実装する方法
-
[解決済み] デザインパターン 抽象ファクトリーとファクトリーメソッド
-
[解決済み] FacadeパターンとAdapterパターンの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] デザインパターンについて。シングルトンはいつ使うべきですか?
-
[解決済み】クラスの命名 - すべてを"<WhatEver>Manager "と呼ぶのを避けるには?[クローズド]
-
[解決済み】Proxy、Decorator、Adapter、Bridgeの各パターンの違いとは?
-
[解決済み】ラッパークラスとは何ですか?
-
[解決済み】ファサードデザインパターンとは何ですか?
-
[解決済み】REST APIのログインパターン
-
[解決済み] テンプレート方式とストラテジーパターンの違いは何ですか?
-
[解決済み] シェルスクリプトのデザインパターンやベストプラクティス [終了しました]。
-
[解決済み] Observerデザインパターンと "Listeners "の比較
-
[解決済み] リポジトリとサービスの違い?