처음에 작성했던 코드는 다음과 같다.

class LoginViewModel : ViewModel() {

    private val _loginResult = MutableLiveData<LoginResult>()               //로그인
    val loginResult: LiveData<LoginResult> = _loginResult   
    private val _registerResult = MutableLiveData<LoginResult>()            //회원가입
    val registerResult: LiveData<LoginResult> = _registerResult
    private val _findIDinResult = MutableLiveData<LoginResult>()
    val findIDinResult: LiveData<LoginResult> = _findIDinResult             //ID찾기
    private val _findPWResult = MutableLiveData<LoginResult>()
    val findPWResult: LiveData<LoginResult> = _findPWResult                 //PW찾기



    fun requestFindID(){
        if(TODO("아이디찾기")){
            _findIDinResult.value = LoginResult(true)
        } else {
            _findIDinResult.value = LoginResult(false)
        }
    }
    fun requestFindPW(){
        if(TODO("비밀번호찾기")){
            _findPWResult.value = LoginResult(true)
        } else {
            _findPWResult.value = LoginResult(false)
        }

    }
    fun requestCheckNickname(nickname: String){
        if(TODO("회원가입")){
            _registerResult.value = LoginResult(true)
        } else {
            _registerResult.value = LoginResult(false)
        }
    }
    fun requestRegister(request : RegisterRequest){
        if(TODO("회원가입")){
            _registerResult.value = LoginResult(true)
        } else {
            _registerResult.value = LoginResult(false)
        }
    }



    fun login(username: String, password: String, autoLogin : Boolean = false) {
        if (isUserNameValid(username) && isPasswordValid(password)) {
            //로그인 검증 과정생략
            _loginResult.value = LoginResult(true)
        } else {
            _loginResult.value = LoginResult(false)
        }
    }



}

 

 

LoginActivity에서 사용하는 LoginViewModel에서

    1. 로그인

    2. 회원가입

    3. 아이디 찾기

    4. 비밀번호 찾기

 

4가지 요청에 대해 서버에서 검증 결과를 받아와야 하는데

Observer 패턴을 사용하여 결과값이 넘어오는 과정을 보기 위해서 총 4개의 LiveData를 제작했었다.

 

연관된 행동(하나의 액티비티에서 들어온 요청에 대한 검증)이 각각 따로 적혀 있어 난잡해 보인다.

 

class LoginViewModel : ViewModel() {
    private val repository = UserRepository()

    val _response = MutableLiveData<LoginResponse>()
    val response : LiveData<LoginResponse> = _response
    val request : (LoginRequest) -> Unit

    init {
        request = { requestType ->
            val dto = requestType.dto
            viewModelScope.launch {
                when(requestType){
                    //로그인
                    is LoginRequest.Login -> {
                        if ((isUserNameValid(requestType.dto.email) && isPasswordValid(requestType.dto.password))) {
                            _response.value = LoginResponse.Login(repository.login(dto))
                        }
                    }
                    //회원가입
                    is LoginRequest.Register -> {
                        _response.value = LoginResponse.Register( repository.register(dto))
                    }
                    //아이디찾기
                    is LoginRequest.FindPW -> {
                        _response.value = LoginResponse.FindIdPw(repository.findID(dto))
                    };
                    //비밀번호찾기
                    is LoginRequest.FindID -> {
                        _response.value = LoginResponse.FindIdPw( repository.findPW(dto) )
                    };
                }
            }

        }
    }
}

sealed class LoginRequest() {
    abstract val dto: UserRequestDTO
    data class Login(override val dto : LoginRequestDTO) : LoginRequest()
    data class FindPW(override val dto : FindPwRequestDTO) : LoginRequest()
    data class FindID(override val dto : FindIdRequestDTO) : LoginRequest()
    data class Register(override val dto : RegisterRequestDTO) : LoginRequest()
}

sealed class LoginResponse{
    abstract val dto : UserResponseDTO
    data class Login(override val dto : LoginResponseDTO) : LoginResponse()
    data class FindIdPw(override val dto : FindResponseDTO) : LoginResponse()
    data class Register(override val dto : SuccessResponse) : LoginResponse()

 

우선 Activity에서 요구할 수 있는 Request들을 각각 Data Class로 생성하여 LoginRequest로 묶어줬다.

request와 response의 종류가 sealed class로 묶여져 있어 한눈에 파악이 가능했으며,

어떤 요청을 수행하든 결과를 response 라이브 데이터에 LoginResponse 클래스로 넣게 되면, 해당 값을 Observe하는 Activity Component에서 해당 결과에 대한 타입을 구분하여 UI에 반영해 줄 수 있었다.

 

 

추가적으로 각각의 요구에 대해 Repository 단에서 필요로 하는 양식들을 UserResponseDTO, UserRequestDTO로 묶어 선언해 줌으로써 OCP 개념을 준수하기 위해 노력했다.

 

예를 들어 추가적인 '이름검색'과 같은 요청이 필요하다 싶으면 , UserRequestDTO와 LoginRequest에만 해당 항목을 추가하면 되므로 기존에 구현된 항목에 대한 수정을 불필요하게 된다.

 


android/codelab-biometric-login (github.com)

 

GitHub - android/codelab-biometric-login

Contribute to android/codelab-biometric-login development by creating an account on GitHub.

github.com

 

지문인증과 관련된 code-lab인데 해당 코드에서는 제외하였지만, 로그인 구현 과정에서 많이 참고하였다.

+ Recent posts