[우테코 7기] 모바일 프리코스 1주차 회고록

우테코에 지원하기까지 동기 비슷한것

올해는 목표를 잃고 많이 방황했다. 부모님, 특히 어머니가 공무원을 너무 바라셔서 7급 전산직 공무원 응시자격을 갖추기 위해 반년 이상을 날려먹었다. 코딩은 흥미가 있지만 PSAT같은 능지테스트와 산수 문제들은 진짜 하기 싫었다. (공부해도 실력이 오르는거 같지도 않는걸…)

정체성 자본 쌓기 (유튜브 비셀프)

 

솔직히 내가 무슨 개발자가 되고 싶은지 학교를 다닐 때에도 그닥 고민을 해본적이 없었다. 유니티도 해보고 웹도 건드려보고 그렇다고 단순히 백엔드 개발자가 취업이 잘된다는 이유로 선택하고 싶진 않았다.

곰곰이 생각해본 결과 졸업작품 으로 안드로이드 앱을 제작했던것이 나름 성과도 있었고 (코틀린이나 Jetpack같은건 쓰지도 않았고, 디자인 패턴이나 객체지향 원칙 등은 참고도 하지 않은채 천조각을 기워내듯이 완성했지만…) 중학교 시절 단순히 안드로이드 개발자가 되고 싶어서 닉네임도 저렇게 지었겠다... 모바일 개발자를 해야 겠다고 생각했다

이쯤이면 충분하게 방황은 한 것 같으니 선택과 집중을 통해 모바일 개발자로 용감하게 뛰어들어 정체성 자본을 쌓을 때라고 생각했고 우테코가 적격이라는 결론에 도달했다. 우연히 보게 된 유튜브 영상을 보고 마음을 굳히게 되었다. 

우테코가 안받아주면 SSAFY도 계속 문 두드려보고 안되면 국비 아무거나 들어야지 뭐…


[1주차] 문자열 덧셈 계산기

🚀 입력한 문자열에서 숫자를 추출하여 더하는 계산기를 구현한다.

  • 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다.
    • 예: "" => 0, "1,2" => 3, "1,2,3" => 6, "1,2:3" => 6
  • 앞의 기본 구분자(쉼표, 콜론) 외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 "//"와 "\n" 사이에 위치하는 문자를 커스텀 구분자로 사용한다.
    • 예를 들어 "//;\n1;2;3"과 같이 값을 입력할 경우 커스텀 구분자는 세미콜론(;)이며, 결과 값은 6이 반환되어야 한다.
  • 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 한다.

 입력

  • 구분자와 양수로 구성된 문자열 ( //|\\n1|2;3,4 )

 출력

  • 덧셈 결과 ( 결과 : 6 )

1주차 과제 구현 리포지토리

 

GitHub - medAndro/kotlin-calculator-7: 문자열 덧셈 계산기 미션 저장소

문자열 덧셈 계산기 미션 저장소. Contribute to medAndro/kotlin-calculator-7 development by creating an account on GitHub.

github.com

 

 

1주차 과제 시작 전

평소에 코드를 쓰레기같이 작성하고 있어서일까…

"안돌아가는 프로그램보다 돌아가는 쓰레기가 낫다" 라는 말을 참 좋아한다. 우테코를 관통하는 격언?이기도 하다.

물론 작동되는게 중요하지만 협업을 위해서는 가독성과 유지보수성을 잡는것도 중요할 것이다..

그동안은 돌아가서 학점만 받으면 그만이었다.

 

지금까지 가지고있던 코딩 습관을 버리고 클린 코드와 객체지향 원칙들을 지키기 위해 나름 여러가지 찾아봤는데 벌써 머리가 아파왔다. 코틀린 언어에 익숙해지지도 않은 상태이기도 하고 이번주는 일단 코드를 기능 단위로 분리하는것과 코드 재사용을 해볼것 그리고 주석을 상세히 달 것을 목표로 진행하기로 하였다.

물론 돌아가는 코드를 만들것이 목표 0순위이다.

 

요구사항 분석과 초기 구현 과정

과제를 처음 보자마자 학습 목표가 “개발 환경에 익숙해지는것” 그리고 “간단한 문제 해결”이라 되어있어 가벼운 워밍업 과제로 생각하고 접근했었는데 생각보다 고민해야 할 거리가 많았던 과제였다….

우선 구현할 기능 목록을 정리하라는 요구사항이 있어 코딩테스트 문제 풀듯이 대강 훑어보고

  1. API로 문자열을 입력받고
  2. 쉼표와 콜론 구분자를 Set에 저장하고 커스텀 구분자가 있으면 추가하고
  3. 2번에서 저장한 구분자들로 문자열을 나누어 더한다

이 순서로 구현을 하고 마지막으로 잘못된 입력값을 예외 처리하는 코드를 추가하기로 하였고 이걸로 간단하게 끝인줄 알았다.

 

요구사항 재분석과 리팩터링

찝찝한 느낌에 요구사항을 다시 보니 입력은 “양수”였다는 것을 뒤늦게 알아챘고. 조건을 빡빡하게 설정해둔 코딩테스트 풀듯 별 의심없이 “양의 정수”일것이라 지레짐작해서 처음 프로젝트를 완성했던 것이 오산이었다. “양수”는 음수와 0이 아닌 정수와 실수를 모두 의미하니 0과 0.0을 입력 오류로 처리하고 양의 정수만 고려하던 코드를 실수를 포함하도록 설계하여야 했다.

그리고 커스텀 구분자는 “문자”라는건 처음부터 인지는 하고 있었지만 다시 확실히 해둘 필요가 있다고도 생각했다. “기능 요구 사항에 기재되지 않은 내용은 스스로 판단하여 구현”하랬으니 Char타입으로 저장이 가능한 것을 문자라고 판단하고 구현하기로 하였다. 이렇게 되면 대다수의 이모지(👀)는 구분자로 사용이 불가능하게 된다는점은 인지하고 있었지만 편의상 그렇게 제한했다.

느낌표는 감탄사인가 팩토리얼인가… 스스로 판단할것

 

커밋 컨벤션 그리고 커밋 주기

깃허브를 “코드 쓰레기통”으로 이용하고 있던터라 당연히 처음 고민했던 내용이었다. 그나마 익숙하게 쓰고있던 소스트리를 이용했다. (IntelliJ에서도 되지만 뭔가 잘못 건드릴까봐 불안했다)

  • feat : 새로운 기능 추가
  • fix : 버그 수정
  • docs : 문서 관련 (README등)
  • style : 스타일 변경 (포매팅 수정, 들여쓰기 추가, …)
  • refactor : 코드 리팩토링
  • test : 테스트 관련 코드
  • build : 빌드 관련 파일 수정
  • ci : CI 설정 파일 수정
  • perf : 성능 개선
  • chore : 그 외 자잘한 수정

 

일단 커밋 메세지는 헤더와 메시지 정도만 한글로 올바르게 작성하려고 노력했다.

스코프는 뭘 써도 이상한것 같아서 애초에 옵션이니 과감하게 생략했다.

컨벤션 헤더로 끊을 수 있는 단위의 수정사항만 반영해서 커밋후 푸시하려고 노력은 했는데 깃을 쓰지 않고 혼자 개발하던 습관이 익어서 그런지 하나의 커밋에 여러 컨벤션 헤더에 해당되는 내용이 짬뽕되는 경우가 있었고 이미 작성된 부분을 수동으로 되돌려 최소 단위로 분리후 커밋하는 방식으로 해결하곤 했는데 "논리적이고 의미 있는 단위"로 커밋하기 위해 깃에 익숙해지는 수밖에 없다는 생각이 들었다.

 

주석 과유불급 그리고 KDoc

평소에 주석을 안쓰고 코딩하는 버릇이 있어서 이번 과제에서 강박적으로 주석을 달았으나 오히려 가독성만 해치는 느낌을 받았고 의미없는 주석은 걷어내는편이 좋다는걸 알게 되었다.

변수명으로 최대한 무엇을 하는 코드인지 드러내고 쓸데없는 주석을 걷어냈으며 주석을 더욱 효율적으로 달기 위해 KDoc 주석을 도입해보었다. 문서화 주석을 생성하기 위하여 사용한다고 하지만 그냥 사용해도 IntelliJ에서 메소드에 마우스를 올리면 동작과 입출력 힌트를 보여주는데 사용되기 때문에 훨씬 보기 좋고 코드 덕지덕지 붙어잇던 주석을 걷어내어 가독성도 높아졌다고 생각했다.

 

Pull Request와 과제 제출

가이드에 제출방법이 자세히 나와있어서 어려운건 없었다.

예상대로 한번에 통과했고 예제 테스트가 2개밖에 없어서 0이나 양의 실수 처리같은건 고려 안해도 아마 맞게 해주지 않을까 싶긴 하다.

 

이번 과제를 통해 알게 된 코틀린

  • 컬렉션에 무언가 있는지 검사할때 in 연산자를 쓰는 게 권장된다는 것
    • 물론 자바에서처럼 .contains()도 작동 한다.
    • !in 으로 존재하지 않는지 검사하는것도 가능하다
    • 자바와는 다르게 파이썬스럽다고 느꼈다.
  • 컬렉션 간의 -연산으로 차집합의 컬렉션을 만들 수 있다는 것
    • Set을 하나하나 순회해서 제거하고 있었는데 그냥 빼버리는게 가능했다…
  • 숫자를 그 자체로 문자로 변환하려면 toChar()가 아닌 digitToChar()를 사용해야 하는 것
    • toChar()를 쓰면 숫자에 해당하는 ASCII코드가 문자로 변환된다….
  • 확장 함수를 이용해 기존 클래스에 기능을 추가할 수 있다는 점

 

그리고 숙제로 남은것

디자인 패턴

  • 솔직히 적용 해본적이 없다. 다른거 챙기는것도 정신없어서 1주차에서 일단은 보류했다.

테스트 주도 개발(TDD), JUnit,  AssertJ, 그리고 단위테스트

  • 과제를 마치고 프로젝트에 내장된 예제로 테스트 코드를 그대로 확장하여 입력값을 검사해본 정도로만 사용했는데 자세히 알아보고 시도해봐야 할것 같다.

객체지향 프로그래밍

  • 이번 과제는 객체의 생성 없이 절차 지향으로 짜는게 더 편하지 않을까 싶었다… 따라서 코틀린에서 싱글톤 패턴을 구현하는 객체인 object로 전부 구현했는데 이게 내가 객체지향적으로 프로그래밍 했다는게 맞는건지 절차지향 코드를 쪼개서 늘어놓은건지 의문이 들었다.