티스토리 뷰

이번주 스터디에서는 MVVM패턴 공부를 시작했다


 MVVM 패턴 

구조

 

  • View : 사용자와 상호작용하는 UI, 데이터 변화 감지를 위한 옵저버를 가짐  (ex. Activity, Fragment)
  • Model : 앱에서 사용하는 데이터와 그 데이터를 처리(통신)하는 역할 (ex. dataClass, Repository)
    • Repository : 데이터 API를 가지는 클래스, 뷰모델은 DB에 직접 접근하지 않고 repository에 접근하여 앱의 데이터를 관리
  • View Model : 뷰와 모델 사이의 인터페이스, 데이터바인딩을 전달하며 뷰를 그리기 위한 데이터를 처리하는 역할
    • Live Data : 관찰이 가능한(Observable) 데이터 홀더 클래스, 데이터가 변경될때마다 내부적으로 자동으로 알려줌

동작

  1. View를 통해 사용자 action을 받는다.
  2. ViewView Model로 action을 전달한다.
  3. View Model에서 비지니스 로직을 수행한다.
  4. View ModelModel에게 데이터를 요청한다.
  5. ModelView Model의 요청에 응답한다.
  6. View Model은 응답받은 데이터를 가공하고 저장한다.
  7. View Model은 Data Binding을 통해 View를 수정한다

 


 

Repository 패턴 적용

  • 필요한 데이터를 처리하는 부분을 비지니스 로직에서 분리시키기 위해 사용되는 디자인 패턴

폴더링

  • 얼리버디의 기존 회원가입 코드를 수정
  • data폴더 안에 datasource와 repository라는 두개의 폴더를 가진다. 
  • data/datasource/model 폴더는 통신에 필요한 data class를 가진다
  • data/datasource/remote/retrofit 폴더는 기존에 쓰던 networkService코드를 가진다.
  • data/datasource/remote 폴더는 인터페이스를 정의하는 RemoteDataSource와 인터페이스를 구현하는 RemoteDataSourceImpl을 가진다.
  • data/repository 폴더는 앱의 데이터를 관리하는 repository 클래스들을 가진다.

RemoteDataSource

interface RemoteDataSource { //필요한 함수들을 모아서 정의하는 인터페이스
    	fun signUp(jsonObject: JsonObject, //post에 필요한 값을 보낼 body
        	   onResponse: (Response<PostSignUpData>) -> Unit, //통신 성공시 수행할 함수
        	   onFailure: (Throwable) -> Unit) //통신 실패시 수행할 함수
}

RemoteDataSourceImpl

class RemoteDataSourceImpl: RemoteDataSource { //RemoteDataSource를 상속받는 클래스
    override fun signUp(
        jsonObject: JsonObject,
        onResponse: (Response<PostSignUpData>) -> Unit,
        onFailure: (Throwable) -> Unit
    ) {
        SignUpServiceImpl.SERVICE.postSignUpData(jsonObject).enqueue(object : //enqueue 함수 실행
            Callback<PostSignUpData> {
            override fun onFailure(call: Call<PostSignUpData>, t: Throwable) { //통신 실패시 실행되는 함수 구현
                onFailure(t)
            }

            override fun onResponse( //통신 성공시 실행되는 함수 구현
                call: Call<PostSignUpData>,
                response: Response<PostSignUpData>
            ) {
                onResponse(response)
            }
        })
    }
}

SignUpRepository

class SignUpRepository {
    val retrofitRemoteDataSource: RemoteDataSource = RemoteDataSourceImpl() //인스턴스 생성
    fun signUp(
        jsonObject: JsonObject,
        onResponse: (Response<PostSignUpData>) -> Unit,
        onFailure: (Throwable) -> Unit
    ){
    	//생성한 인스턴스로 RempteDataSourceImpl에 구현해놓은 함수 실행
        retrofitRemoteDataSource.signUp(jsonObject, onResponse, onFailure)
    }
}

SignUpActivity

val signUpRepository = SignUpRepository()
        
signUpRepository.signUp(jsonObject = body,
	onResponse = { //고차함수로 구현, it으로 response에 바로 접근 가능
	if (it.isSuccessful){
		val intent = Intent(this@MainActivity, SuccessActivity::class.java)
		startActivity(intent)
	}else
		Log.e("postUserData 응답 실패 : ", it.message())
	}, onFailure = { //고차함수로 구현, it으로 t에 바로 접근 가능
		Log.e("통신 실패 error : ", it.toString())
	}
)

동작

  1. SignUpActivity에서 repository클래스의 인스턴스 생성 후 repository에 구현되어 있는 함수 호출
  2. SignUpRepository에 들어가 RemoteDataSource 인터페이스 타입의 인스턴스 생성 후 RemoteDataSource에 구현되어 있는 함수 호출
  3. RemoteDataSource 인터페이스를 상속받아 구현하는 RemoteDataSourceImpl로 들어가 구현된 함수 실행
  4. SignUpServiceImpl 클래스의 SERVICE객체로 통신 함수를 실행

 

 

참고자료🕊

 

[Android] MVVM & 안드로이드 아키텍쳐 컴포넌트 시작하기

(나를 포함한) 안드로이드 개발을 처음 시작하는 사람들은 대부분 액티비티에 거의 모든 코드를 직접 넣는다. 하지만 시간이 갈수록 액티비티는 점점 무거워지고, 수정이나 유지 보수 하기가 힘들어진다. 흔히 비 구조적이고 유지보수가 어려운 코드를 스파게티 코드하고 하는데, 나의 첫 프로젝트는 스파게티에 라면 사리 다섯 개 정도 추가한 모습과 같았다. 때문에 디자인 패턴 공부의 필요성을 마음 깊이 느끼게 됐다. 이제 인싸 안드로이드 개발자라면 다들 MVVM에 D

blog.yena.io

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함