MVVM パターン
Model, View, ViewModel
MVVMパターンは、MVCパターンからコントロールラーを抜き、ViewModelを追加したパターン
それぞれの概念が独立的に存在し、テスト、メンテナンス、再利用が容易だが、設計するのが難しく、それでも慣れれば簡潔なコードでアンドロイドでもMVMを好むという。
- Model
-> データを意味するオブジェクト
DataModelとも呼ばれ、DB、Network、共有Preferenceなど
さまざまなデータ ソースから必要なデータを用意する。
ViewModelからデータを取得できるようにデータを準備
- View : xmlファイル -> 見せるもの
- ViewModel : Viewを表現するために作ったViewのためのModel
Viewを示すためのデータ処理担当
ViewとはBindingを行い、接続後にViewからアクションを受け、Viewをアップデートする
ex) textViewに表示する内容を担当する関数など、Viewで変化が起きるViewControllerの役割を担当
MVVMと主に一緒に使用される概念
* DataBinding * LiveData / ViewModel * Android Di(Koin,Dagger) : Hilt依存性注入ViewはViewModelを知っているが、ViewModelはViewを知らず、
ViewModelはModelを知っているが、ModelはViewModelを知らない。
すなわち、一方の方向にのみ依存関係があるので、各モジュール別に分離して開発することができる。
Repositroyを使って気づかれないようにすること
-
Viewに入力が入ると、ViewModelに命令する。
-
ViewModelは必要なデータをModelに要請
-
ModelはViewModelに要求されたデータを応答
-
ViewModelは、応答を受けたデータを加工して保存します。
-
ViewはViewModelとのData Bindingにより自動的に更新
長所 :
- ViewとModelの間の依存性がない。
-> ViewはViewModelのデータだけを眺めており、ViewModelがModelにデータを要請して最新化する。
- ViewとViewModelをバインディングするため、コードの量が減る
-> findViewId()で一つずつ与えることをしなくても良い
-> また、データを注入したり接続したりする作業をしなくてもよい。
(ViewがViewModelの値を見ていて自動更新されるためLive Dataで見るんだよね?)
- Model、View、ViewModelの部分が独立しているため、モジュール化して開発することができる。
MVC、MVPモデルの最終進化形態、それでアンドロイドが好むようだ
短所 :
1.MVVMを作るのは難しいが慣れれば良いコード簡潔性になる
2.簡単なUIではむしろ面倒
3.複雑になるほど、コントロールラーのようにViewModelが急速に肥大化する。
or)
AAC ViewModelとMVVMのViewModelは同じではない
AAC ViewModelはViewModelProvidersを使ってViewModelを作る
AAC ViewModelは、該当アクティビティに一つだけ存在する
DataBinding
Viewにデータを入れる時、ActivityやFragmentで行うことをバインディングが処理してくれる
データをXml ですぐに使用できるため、Live Data と一緒に使用する。
-> LiveDataと一緒に書くと、LiveDataのObserverを使う必要なく
Dataが変更された時、すぐにXmlに反映させることができる。
(=LifeCycleOwner)
BindingAdapterを使用すると、Viewに関連するコード(RecyclerView、Glide、Viewロジック)をActivity、Fragmentからコードを分離し、可読性が良くなる
ViewのデータをActivityでセットするのではなく、xmlからViewModelの値を直接取得する方法
Activityにはロジックだけのためのコードだけが残り、Viewに関連する作業はxmlファイルに定義される。
-> DataBinding = DataとViewを接続する作業をレイアウト(xml)で処理する技術
xmlファイル構造
<layout>
<data>
<variable
name="" // xmlで使用する変数名
type=""/> // クラスおよび関数ファイルパス
...
</data>
</layout>
LiveData
アンドロイドLifeCycleを持っているDataType
-> Life Cycle を持っているため、Life Cycle の中でのみ動作する。
Observerオブジェクトを使用してLive Dataの中にデータアップデートを確認することができる。
-> LifeCycle Ownerの値が変更されると自動的に値を更新してくれるため
開発者が直接管理しなくてもよい。
DataBindingと一緒に使えば、Observerを使わずに簡単にViewの値を更新することができる。
LiveData おおよその構造
val getAllData: LiveData<List<Write>> = repository.getAllData.asLiveData()
ViewModel
ViewModelを使用する理由はUIとロジックの分離である。
ActivityとFragmentはUIをアップデートすることだけに集中でき、ViewModelにあるデータはActivityとFragmentのライフサイクルから自由になる。
したがって、UIとデータ処理ロジックを分離させれば、メンテナンスと開発効率が高くなるのだ。
また、ViewModelにあるデータは、まるでSingtonオブジェクトのように使用できるため、Fragmentの間でViewModelを利用してデータを簡単に共有することができる。
Room
RoomはSQLiteデータベースの上にあるデータベースでSQLiteの短所を補完したもの
Roomは、開発者がSQLiteOpenHelperを使用して処理していた一般的な作業を処理します。
RoomはDAOを使用してデータベースにクエリを実行します。
基本的にUI性能の低下を防止するため、Roomでは基本スレッドでクエリを実行することができず、RoomクエリがFlowを返すと、クエリは自動的にバックグラウンドスレッドで非同期的に実行されます。
RoomはSQLite問い合わせのコンパイル時間の確認を提供します。
Roomデータベースクラスは抽象クラスで、RoomDatabaseを拡張する必要があります。 通常、アプリ全体にRoomデータベースインスタンスが1つだけあればいいです。
@Database(entities = arrayOf(Word::class), version = 1, exportSchema = false)
public abstract class WordRoomDatabase : RoomDatabase() {
abstract fun wordDao(): WordDao
companion object {
@Volatile
private var INSTANCE: WordRoomDatabase? = null
fun getDatabase(context: Context): WordRoomDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
WordRoomDatabase::class.java,
"word_database"
).build()
INSTANCE = instance
instance
}
}
}
}
-
Roomのデータベースクラスは、
abstract
で、RoomDatabase.
を拡張する必要があります。 -
クラスをRoom データベースになるように
@Database
で注釈処理し、注釈パラメータを使用してデータベースに属する項目を宣言し、バージョン番号を設定します。 各アイテムは、データベースに作成されるテーブルに相当します。 データベース移転はこのCodelabの範囲外なので、exportSchema
はビルド警告を避けるためにfalseに設定しました。 実際のアプリでは、現在のスキーマをバージョン制御システムで確認できるように、スキーマをエクスポートするために使用するRoomディレクトリを設定することをお勧めします。 -
データベースは、各「Dao」の抽象「getter」メソッドを介してDAOを露出します。
-
データベースの複数のインスタンスが同時に開くのを防ぐために、
WordRoomDatabase
をシングルトーンと定義 -
getDatabase
はシングルトンを返します。 初めてアクセスするときにデータベースを作成し、Roomのデータベースビルダーを使用してWordRoomDatabase
クラスのアプリケーション コンテキストでRoomDatabase
オブジェクトを作成し、名前を"word_database"
と指定します。
参考
https://jhtop0419.tistory.com/m/21
https://kangmin1012.tistory.com/16?category=879935
https://kangmin1012.tistory.com/18?category=879935
https://velog.io/@mingyun12304/Android-KotlinViewModel-LiveData
https://aonee.tistory.com/48
https://developer.android.com/codelabs/android-room-with-a-view-kotlin?hl=ko#0
https://tech.nri-net.com/entry/mvvm_in_android