본문 바로가기

카테고리 없음

우테코 지난 3번의 미션을 돌아보며

 

 안녕하세요. 우아한 테크코스 프리코스에 참여하고 있는 개발자 정찬호입니다. 오늘은 지난 3주간의 프리코스 과정을 통해 스스로 느낀 점과 간단한 미션 수행 코드를 리뷰하고 회고하는 시간을 가지려 합니다. 다른 열정 많으신 참가자분들처럼 저 또한 주차마다 회고글을 쓰고 싶었지만 미션을 수행하면서 스스로 반성해야 할 점들을 너무나 많이 깨달았기에 이 문제들을 모두 개선해야지만 회고글을 쓰겠다는 조금은 이상한 다짐을 하게 되었습니다.

첫 번째 미션 리뷰

https://github.com/chanho0908/kotlin-calculator-7/tree/chanho0908

 

GitHub - chanho0908/kotlin-calculator-7

Contribute to chanho0908/kotlin-calculator-7 development by creating an account on GitHub.

github.com

첫 미션을 보고 느낀점은 생각보다 할만한데?라고 느꼈고 평소 하던 대로 문제만 해결해서 코드를 제출했습니다. 그러나 첫 주차가 끝나고 나니 이는 참 어리석은 생각이었습니다. 다른 분들의 코드를 리뷰하면서 다양한 아키텍처, 디자인 패턴, 에러 처리 등 많은 요소들의 열정과 노력이 보였습니다. 그에 비하면 제 프로젝트는 참으로 성의 없었죠. 많은 반성을 했습니다. 그래서 제가 추구하고자 하는 개발자의 모습으로써 성장하기 위해 우테코에선 어떤 노력을 해야 할지 고민했습니다. 

 

그중 하나는 에러 처리에 대한 디테일이 중요하다고 생각했습니다. 당장에 숫자 하나만 입력받는 상황에서도 이 숫자가 정수인지, 소수인지 아니면 정수가 맞는지, Int형으로 표현 가능한 범위를 초과하는지 등 정말 다양한 엣지 케이스들이 있었습니다. 그래서 이런 케이스들을 문서로 정리하고 이를 바탕으로 문제를 풀어나가려 했습니다.

 

또한 개발자로써 좋은 개발자라고 할 수 있는 많은 요소들이 있다고 생각합니다. UI를 정말 예술로 그려내는 개발자, UX로 유저의 만족도를 끌어올리는 개발자 등등 많겠지만 저는 그중에서도 아키텍처를 잘 설계하는 개발자가 되고 싶습니다. 그래서 전 남은 3번의 미션에서 모두 다른 아키텍처를 사용하기로 다짐했습니다. 

두 번째 미션 리뷰

https://github.com/chanho0908/kotlin-racingcar-7

 

GitHub - chanho0908/kotlin-racingcar-7

Contribute to chanho0908/kotlin-racingcar-7 development by creating an account on GitHub.

github.com

두 번째 미션에선 첫 번째 미션에서 저지를 실수를 되풀이하지 않도록 스스로 몇 가지 규칙을 정했습니다. 먼저 문제의 요구 사항 중 누락된 부분이 있었기 때문에 이는 제가 문제를 정확히 파악하지 않았기 때문이라고 생각했습니다. 그래서 문제를 보고 바로 푸는 것이 아닌 최소 하루 이상은 코드를 치지 않고 문제를 정확히 이해하는 시간을 가지도록 했습니다. 또한 체크 리스트와 에러 처리 명세서를 작성하여 다양한 에지 케이스들을 놓치지 않도록 꼼꼼하게 리뷰하려 했습니다. 

 

이번 미션에서 제가 시도한 아키텍처는 MVI였습니다. 코드에 대한 설명은 이 글을 참조해주세요. MVI를 정말 열심히 공부하며 적용했지만 미션이 마감되고 나서야 또 요구 사항을 잘못 구현했단 것을 깨달았습니다. 더군다나 제출이 마감되고 리팩토링 하다가 아무 생각 없이 커밋을 푸시하는 바람에 마감 후 푸시 금지라는 규칙을 어기게 되었습니다. 그래서 해당 커밋을 제거하려다 PR이 닫혀버리는 대참사가 발생했죠... 당시의 감정을 되살려 반성글을 작성했었습니다. 2주차까지 참으로 다사다난했습니다. 

 

여러 번의 실수로 망쳐버린 프리코스를 어떻게 해야 할지 너무나 막막했습니다. 이대로 탈락일까...? 그래도 이미 지난 일 실수는 잊고 앞으로의 미션을 더 잘하고는 다짐으로 3주 차를 맞이했습니다.

세 번째 미션 리뷰

https://github.com/chanho0908/kotlin-lotto-7

 

GitHub - chanho0908/kotlin-lotto-7

Contribute to chanho0908/kotlin-lotto-7 development by creating an account on GitHub.

github.com

세 번째 미션에선 모바일 클린 아키텍처를 지향해서 미션을 수행했습니다 . 이번 미션에서 가장 재미있었던 점은 enum class에 대한 활용이었습니다. 저는 그동안 Sealed Class를 통해서 상태 관리 클래스를 만들어 ViewModel에서 상태에 따라 분기하는 코드를 만드는 스타일을 선호했습니다. 이유는 코드의 가독성 때문인데요, if-else문을 사용하는 것보다 when을 사용해 명확한 상태에 따라 분기하는 것이 더 가독성이 좋다고 생각했기 때문입니다. enum Class는 자바로 디컴파일시 absract class로 변환됩니다. 저는 개인적으로 enum Class와 Sealed Class는 역할과 쓰임새가 비슷하지만 Sealed Class는 코틀린에만 있는 유니크한 문법으로 조금 더 코틀린스러운 코드를 만들 수 있다고 생각해 Selead Class 사용을 선호했습니다.

 

하지만 이번 미션을 하고 나니 둘의 쓰임새가 명확히 다르단 것을 느꼈습니다. Enum Class는 상태를 표현하기 보단 상수들을 관리하는데 특화된 것 같습니다.  아래와 같이 에러 상태에 출력할 메시지를 관리하는 Enum Class를 만들어 에러 메시지들을 관리하도록 하였습니다. 이렇게 하면 에러 상태들은 Sealed Class로 관리하고 에러 상태에 따라 보여줄 메시지들은 Enum Class로 관리할 수 도 있었겠네요.

enum class Exception(private val msg: String) {
    EMPTY_INPUT("빈 값이 입력 되었어요."),
    INVALID_INPUT("정수만 입력해주세요."),
    INVALID_FORMAT("숫자와 구분자 쉼표(,)만 입력해주세요."),
    INVALID_UNIT("구입 금액은 천원 단위로만 입력해주세요."),
    EXCEED_MAX_INT("입력한 값이 범위를 벗어났어요."),
    EXCEED_INPUT("로또 번호는 1부터 45 사이의 숫자여야 합니다."),
    INVALID_SIZE("당첨 번호는 6개를 입력해주세요."),
    INVALID_LOTTO_SIZE("로또 번호는 6개여야 합니다."),
    INVALID_DUPLICATED("당첨 번호는 중복될 수 없어요."),
    BONUS_NUMBER_DUPLICATED("보너스 번호와 당첨 번호는 중복될 수 없어요.");

    override fun toString(): String = "$ERROR $msg"

    companion object {
        private const val ERROR = "[ERROR]"
    }
}

 

또한 이렇게 format 함수를 사용해 문자열을 포맷팅할 수 도 있었습니다. 이런 것만 봐도 이번 미션에선 정말 많은 것을 배웠네요. 이전에 "도메인 주도 개발 시작하기"란 책에서 이런 방식으로 Enum Class를 사용해 상태를 관리하란 내용이 있었는데 당시 저는 Sealed Class 만들 사용 해도 충분하다고 생각해서 크게 와닿지 않았습니다만 이번 미션을 수행하고 나니 다시 책을 복기해봐야겠네요.

enum class Output(private val msg: String) {
    PURCHASE("%d개를 구매했습니다.");

    override fun toString(): String = msg

    companion object {
        fun purchaseFormat(pay: Int): String {
            return PURCHASE.toString().format(pay)
        }
    }
}

 

이외에도 테스트 코드를 작성하면서 테스트의 중요성에 대해 정말 많이 느끼게 되었습니다. 이전에 제가 앱을 개발할 때나 무언가 작업을 할 때 사용자 입력이 필요한 프로그램은 매번 직접 입력해야 했습니다. 하지만 테스트 코드를 만들고 나니 이런 과정을 생략할 수 있어서 개발하는 과정에서 편의성이 정말 많이 증대되었습니다. 이걸 왜 이제야 했지? 란 생각이 들 정도로 정말 편리했습니다. 그러다 보니 새로운 아키텍처에 대한 관점이 생겼는데요, 바로 테스트하기 편한 코드입니다. 

 

아직 테스트 코드에 대한 지식이 깊지 않아 어떻게 아키텍처를 설계해야 테스트 하기 좋은 코드가 될지 또 테스트 코드는 어떻게 작성해야 좋은 테스트 코드인지 많이 부족하지만 세 번의 미션을 진행하면서 점점 성장해 나가는 것 같습니다.

 

이미 두 번의 큰 실수로 인해 두 번의 미션에서 많이 아쉬운 결과를 냈습니다. 과연 이 여정의 끝이 성공일까요? 실패일까요 ? 그렇다면 무엇이 성공이고 실패일까요 ? 단순히 우테코에 붙는 것이 성공일까요 ? 저는 이 여정의 끝이  탈락이라고 해서 아쉬울지언정 실패는 아닐 거라고 생각합니다. 이미 정말 많은 성장을 하고 테스트라는 새로운 관점을 배울 수 있었으니까요. 당연히 합격이라고 하면 더할 나위 없이 행복하겠지만 탈락하더라도 묵묵히 제 길을 걸어 나가려 합니다.