KotlinにおけるFactoryメソッドの実装方法と使う理由についてまとめました。
目次
Factoryメソッドとは
Factoryメソッドとはデザインパターンの1つで、より柔軟にオブジェクトを生成することを目的とするものです。
インスタンスの作り方をスーパークラスで定め、具体的な処理をサブクラスで行います。
KotlinでFactoryメソッドを実装する方法
Factoryメソッドを実装する方法はいくつかありますが、以下のcompanion objectを使用した方法が推奨されています。
メソッド名としては以下が慣例的によく使われるため、以下のメソッド名を使うのが良さそうです。
- from: 返り値がその型そのものの場合
- of: 複数引数を受け取りそれらを集約するものを返す場合
1 2 3 4 5 6 7 | data class User(val id: Int, val Name: String) { companion object { fun from(userId: number, name: String): User { return User(userId, name) } } } |
使うときは以下のようにFactoryメソッドを呼び出してインスタンスを生成します。
1 2 3 | val userId = 1 val name = “hoge” val user = User.from(userId, name) |
companion objectとは
ちょっと寄り道ですが、companion objectについて説明します。
companion objectはクラス内に作成されるSingletonのことです。Singletonとは、生成するインスタンスの数を1つに制限するデザインパターンです。
Kotlinでは、classの代わりに objectキーワードを使用するだけでSingletonが作成でき、objectキーワードの前にcompanion修飾子を付与することでクラスに属するSingletonが作成できます。
これをcompanion objectと呼び、companion objectは1クラス内に1つだけ宣言可能です。
Kotlinにはstatic修飾子がないので、companion objectはstaticなフィールドやメソッドが必要なときの代替手段として利用されることがあります。
なぜコンストラクタよりFactoryメソッドの方が良いのか
オブジェクトを生成するのになぜコンストラクタよりFactoryメソッドが良いのか、いくつかその理由を挙げていきます。
Factoryメソッドにすることでメソッド名がつけられる
先ほど紹介したように、Factoryメソッドならメソッド名をつけられるため、生成方法ごとにわかりやすい名前をつけられます。
1 2 3 4 5 6 7 | data class User(val id: Int, val Name: String) { companion object { fun from(userId: number, name: String): User { return User(userId, name) } } } |
返り値にサブタイプを指定できる
以下の例のように、listOfメソッドの返り値はList型になっており、Listはinterfaceであるため、Listのサブタイプを返すことができます。
1 | val hogeList: List<int> = listOf(1, 2, 3) |
コンストラクタと異なる引数を渡すことができる
Factoryメソッドならコンストラクタと異なる引数を渡すことができます。
1 2 3 4 5 6 7 | data class User(val id: Int, val Name: String) { companion object { fun of(userId: number, config: Config): User { return User(userId, config.defaultName) } } } |
参考
https://qiita.com/doyaaaaaken/items/0c99da9efa7d724a0d80
https://qiita.com/tkhs0604/items/261e94a42b7097dfd204