Model, View, ViewModel의 약자
MVVM 패턴은 MVC 패턴에서 Controller를 빼고 ViewModel을 추가한 패턴
각각의 개념들이 독립적으로 존재해서 테스트, 유지 보수, 재사용이 쉽지만 설계하는 것이 어려움 그래도 익숙해지면 간결한 코드로 안드로이드에서도 MVVM을 선호 한다고 함.
Model
-> 데이터를 의미하는 객체
DataModel이라고도 하며 DB, Network, SharedPreference 등
다양한 데이터 소스로부터 필요한 데이터를 준비함.
ViewModel에서 데이터를 가져갈 수 있게 데이터를 준비
View : xml 파일 -> 보여주는 것
ViewModel : View를 표현하기 위해 만든 View를 위한 Model
View를 나타내주기 위한 데이터 처리담당
View와는 Binding을 하여 연결후 View에게서 액션을 받고 또한 View를 업데이트한다
ex) textView에 보여줄 내용을 담당하는 함수 등, View에서 변화가 일어나는 ViewController의 역할을 담당
View는 ViewModel을 알지만 ViewModel은 View를 알지 못하고,
ViewModel은 Model을 알지만 Model은 ViewModel을 알지못한다.
즉, 한쪽 방향으로만 의존 관계가 있으므로 각 모듈별로 분리하여 개발 할 수 있다.
Repositroy를 사용하여 알지를 못하게 하는 것 거치게 하는 것
View에 입력이 들어오면 ViewModel에게 명령을 함.
ViewModel은 필요한 데이터를 Model에게 요청
Model은 ViewModel에게 요청된 데이터를 응답
ViewModel은 응답 받은 데이터를 가공해서 저장합니다
View는 ViewModel과의 Data Binding으로 인해 자동으로 갱신
1.MVVM 만드는 것은 어렵지만 익숙해지면 좋은 코드 간결성이 됨
2.간단한 UI에서는 오히려 번거로움
3.복잡해질수록 Controller처럼 ViewModel이 빠르게 비대해진다.
or)
AAC ViewModel과 MVVM의 ViewModel은 같지 않음
AAC ViewModel은 ViewModelProviders를 사용해서 ViewModel을 만듬
AAC ViewModel은 해당 액티비티에서 딱 하나만 존재하게 됨
View에 데이터를 넣을때 Activity나 Fragment에서 하는 걸 바인딩이 처리해줌
데이터를 Xml에서 바로 사용가능하기 때문에 LiveData와 함께 쓰인다.
-> 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>
안드로이드 LifeCycle을 가지고 있는 DataType
-> LifeCycle을 가지고 있어서 LifeCycle안에서만 동작한다.
Observer 객체를 사용해서 LiveData안에 Data업데이트를 확인할 수 있다.
-> LifeCycleOwner가 값이 변경되면 자동으로 값을 갱신해주기 때문에
개발자가 직접 관리하지 않아도 된다.
DataBinding과 함께 쓰게 된다면 Observer를 사용하지않고 손쉽게 View의 값을 갱신할 수 있다.
LiveData 대략 구조
val getAllData: LiveData<List<Write>> = repository.getAllData.asLiveData()
ViewModel을 사용하는 이유는 UI와 로직의 분리이다.
Activity와 Fragment는 UI를 업데이트 하는데만 집중할 수 있고, ViewModel에 있는 데이터는 Activity와 Fragment의 수명주기로부터 자유로워진다.
따라서 UI와 데이터 처리 로직을 분리시키면 유지보수와 개발 효율이 높아지는 것이다.
또한 ViewModel에 있는 데이터는 마치 Sington 객체 처럼 사용이 가능해서 Fragment 사이에서 ViewModel을 이용해 데이터를 쉽게 공유할 수 있다.
Room은 SQLite 데이터베이스 위에 있는 데이터베이스로 SQLite의 단점을 보완한 것
Room은 개발자가 SQLiteOpenHelper를 사용하여 처리하던 일반적인 작업을 처리합니다.
Room은 DAO를 사용하여 데이터베이스에 쿼리를 실행합니다.
기본적으로 UI 성능 저하를 방지하기 위해 Room에서는 기본 스레드에서 쿼리를 실행할 수 없으며 Room 쿼리가 Flow를 반환하면 쿼리는 자동으로 백그라운드 스레드에서 비동기식으로 실행됩니다.
Room은 SQLite 문의 컴파일 시간 확인을 제공
Room 데이터베이스 클래스는 추상 클래스이고 RoomDatabase를 확장해야 합니다. 일반적으로 전체 앱에 Room 데이터베이스 인스턴스가 하나만 있으면 됩니다.
// Annotates class to be a Room Database with a table (entity) of the Word class
@Database(entities = arrayOf(Word::class), version = 1, exportSchema = false)
public abstract class WordRoomDatabase : RoomDatabase() {
abstract fun wordDao(): WordDao
companion object {
// Singleton prevents multiple instances of database opening at the
// same time.
@Volatile
private var INSTANCE: WordRoomDatabase? = null
fun getDatabase(context: Context): WordRoomDatabase {
// if the INSTANCE is not null, then return it,
// if it is, then create the database
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
WordRoomDatabase::class.java,
"word_database"
).build()
INSTANCE = instance
// return 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