Factoryってなぁに〜〜!を考えてみる。

Factoryとは

Factoryは、新しいオブジェクトを生成するための方法を提供してくれるクラス

はにゃ?

Factoryを使用した実例をみてみる

  • ViewModelを作成する
class MainViewModel(application: Application) : AndroidViewModel(application) {

    class Factory(private val application: Application) : ViewModelProvider.Factory {
        @Suppress("UNCHECKED_CAST")
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            when (modelClass) {
                TopViewModel::class.java -> return MainViewModel(application) as T
                else -> throw RuntimeException()
            }
        }
    }
}

ViewModelProvider.Factoryは、ViewModelを作成するためのFactoryのインターフェイス。

Factoryは、ViewModelProvider によって使用され、ViewModelを作成するために呼び出される。

  • ViewModelを呼び出す
class MainActivity : AppCompatActivity() {
	
	private val mainViewModel: MainViewModel by lazy {
        ViewModelProvider(this, MainViewModel.Factory(application))[MainViewModel::class.java]
  }
}

つまり、FactoryはViewModelの生成を手伝うクラスであり、ViewModelProviderがこのクラスを使用してViewModelを作成するということね。

細かく解説

まずは、ViewModelを作成しているコードの解説をおねがいします

  • Factoryクラスは、ViewModelProviderがViewModelのインスタンスを生成する際に呼び出される。
  • Factoryクラスは、どのViewModelのインスタンスを生成するかを決定するためのcreate()メソッドを実装している。
  • create()メソッドは、引数として渡されたClassオブジェクトに基づいて、ViewModelのインスタンスを生成する。この例では、MainViewModelクラスを生成するために使用される。
  • MainViewModelクラスのインスタンスは、applicationオブジェクトを引数にして生成される。この例では、applicationオブジェクトはFactoryクラスのコンストラクタに渡されている。
  • create()メソッドは、生成されたViewModelインスタンスを返す必要があるが、戻り値の型がTとなっている。そのため、as Tというキャストが必要になる。
  • create()メソッドはuncheckedキャストを使用するため、@Suppress(“UNCHECKED_CAST”)というアノテーションが必要。
  • modelClassがMainViewModelクラスでない場合、RuntimeExceptionをスローする。これは、Factoryクラスが生成できるViewModelのクラスが限定されているため。

Tはジェネリックスと呼ばれる機能で、実行時に特定の型に置き換えることができる仮の型を表す。この場合、TはViewModelの型であり、createメソッドが呼ばれる時にその具体的な型が渡されます。具体的な型が渡されるまでT は不明なため、createメソッド内で具体的な型に対応した処理を記述することができない。

create(TopViewModel(application))とすると、TopViewModel固定のインスタンスを返す。

一方で、create(modelClass: Class<T>): Tとすることで、引数で受け取ったmodelClassに基づいて、任意のViewModelのインスタンスを生成することができます。

つまり、ジェネリックスを使うことで、createメソッドをより汎用的に書くことができる。

  • ViewModelを呼び出しているコードの解説

ViewModelを呼び出しているコードの解説もお願いします

  • MainViewModelのインスタンスを生成している。
  • by lazyを使用しているため、mainViewModelプロパティが初めて呼び出されるまで、ViewModelのインスタンスは作成されない。これにより、不要なオブジェクトの生成を避け、パフォーマンスを向上させることができる。
  • ViewModelProvider(this, MainViewModel.Factory(application))は、ViewModelを提供するためのファクトリークラスTopViewModel.Factoryとともに、現在のActivityとApplicationのインスタンスを topViewModel という変数に渡している。
  • これにより、ViewModelがActivityとApplicationのライフサイクルに関連付けられ、適切なタイミングで破棄されるようになる。
  • [TopViewModel::class.java]はViewModelの型を指定している。これにより、ViewModelのインスタンスが生成される。

ちょっと難しいけど、そういう書き方ってことね!

一旦、ノリで乗り切ります。