성장일기

이번 4주 차 미션에서는 3주 차 미션의 학습 목표에 이어 리팩터링을 추가했어요.

 

  1. 클래스(객체)를 분리하는 연습
  2. 도메인 로직에 대한 단위 테스트를 작성하는 연습

 

클래스(객체)를 분리하는 것에 대해 조금 더 깊이 고민해 볼 수 있도록 클래스의 구조와 제약사항을 요구사항에 추가했습니다. 이외에도 프로그래밍 요구사항으로 메서드의 길이를 10줄로 제한하는 등 난이도가 높은 도전 과제를 추가했어요.

 

과제를 제출할 때 이번 주 차 목표를 중심으로 학습하면서 느낀 점을 소감문으로 작성해 주세요. 이때 학습한 '과정’을 잘 드러내 주세요.

 


 

이번 우아한 테크 코스 5기 4주 차 미션은 다리 건너기 게임 미션이다. 자세한 내용은 해당 우테코 깃허브를 통해 공개해놓고 있다.

 

나는 우테코 프리코스 전 과정과 최종 코딩 테스트를 TDD로 도전하며 새로운 인사이트를 얻으며 성장하고 있다. 이번 4주 차가 우테코 프리코스의 마지막 미션이다. 이후 지원서 + 미션 결과 + 소감문을 토대로 1차 합격자 발표를 하고, 1차 합격자들에게만 최종 코딩 테스트 응시 자격이 주어진다.

 

한 달 동안 우테코 프리코스에만 매달렸는데, 많은 성장을 할 수 있는 기회를 준 우테코에게 감사하다고 전하고 싶다. 혹시 참여할지 말지 망설이는 사람이 있다면, 결과에 연연하지 말고 꼭 참여하라고 권해주고 싶다. 해당 주차의 미션이 끝나면 다음 주차의 미션을 기대했었는데, 이제 미션이 없다고 생각하니 아쉽기도 하다. 하지만 프리코스를 통해 앞으로의 공부 방향성을 정할 수 있어서 성장하기 위한 다음 단계로 나아가려고 한다.

 

아래는 1,2,3주차를 TDD미션 요구사항을 진행하며 공부한 점과 느낀 점에 대한 회고록이다.

 

[우아한 테크 코스 5기] 프리코스 1주차 - 온보딩 회고

과제 진행 소감에는 미션을 진행하면서 느끼고 배운 점, 많은 시간을 투자한 부분 등도 포함하면 더 좋을 것 같습니다. 🙂 그리고 과제를 제출할 때 'git’과 '과정별 언어’를 학습하면서 느낀

heesangstudynote.tistory.com

 

[우아한 테크 코스 5기] 프리코스 2주차 - 숫자 야구 게임 회고

2주 차 미션에서는 1주 차에서 학습한 것에 더해 함수를 분리하고, 각 함수 별로 테스트를 작성하는 것에 익숙해지는 것을 목표로 하고 있어요. 이번에 테스트를 처음 접하시는 분들은 언어별 테

heesangstudynote.tistory.com

 

[우아한 테크 코스 5기] 프리코스 3주차 - 로또 회고

지난 2주 차 미션에서는 함수 분리와 함수 별로 테스트를 작성하는 것을 목표로 했는데요. 3주 차 미션에서는 2주 차에서 학습한 것에 2가지 목표를 추가했어요. 클래스(객체)를 분리하는 연습 도

heesangstudynote.tistory.com

 

 

1. 3주 차 공통 피드백을 통한 부족했던 점

우테코 프리코스는 해당 주차의 미션을 완료하면, 해당 주차의 공통 피드백을 문서 형태로 받아볼 수 있다. 정말 뼈와 살이 되는 피드백이다. 공통 피드백을 통해 이전 주차 미션에 대해 부족했던 점을 돌아보며, 다음 미션에서 적용해보려고 노력했다.

 

3주 차의 공통 피드백을 간단하게 정리해 보았다.

  1. 메서드 라인에 대한 기준 - 프로그래밍 요구사항에 함수 15라인으로 제안하는 요구사항이 있는데 main 메서드에도 해당된다. 또한 공백 라인도 한 라인에 해당된다.
  2. 발생할 수 있는 예외 상황에 대해 고민한다. 정상적인 경우를 구현하는 것보다 예외 상황을 모두 고려해 프로그래밍하는 것이 더 어렵다. 예외 상황을 고려해 프로그래밍하는 습관을 들인다.
  3. 비지니스 로직과 UI 로직을 분리한다.
  4. 연관성이 있는 상수는 static final 대신 enum을 활용한다.
  5. final 키워드를 사용해 값의 변경을 막는다.
  6. private 접근 제어자를 이용해 객체의 상태 접근을 제한한다.
  7. 객체는 개체스럽게 사용한다. - 객체의 상태에 접근해 무언가를 하려고 하지 말고, 객체에게 일을 시키고, 메시지를 던져라!
  8. 필드(인스턴스 변수)의 수를 줄이기 위해 노력한다. - 인스턴스 변수가 많은 것은 객체의 복잡도를 높이고, 버그 발생 가능성을 높일 수 있다. 불필요한 필드가 없는지 확인하여 최소화한다.
  9. 성공하는 케이스 뿐만 아니라 예외에 대한 케이스도 테스트한다.
  10. 테스트 코드도 코드다. - 특히 반복적으로 하는 부분을 중복되지 않게 리팩터링 해야 한다.
  11. 테스트를 위한 코드는 구현 코드에서 분리되어야 한다.
  12. 단위 테스트하기 어려운 코드를 단위 테스트 하기
  13. private 함수를 테스트하고 싶다면 클래스 분리를 고려한다. private 메서드가 가독성 이상의 역할을 하는 경우 다른 역할을 수행하는 다른 객체를 만들 타이밍이 아닐지 고려해라.

 

총 13가지의 피드백이 있었다. 피드백을 통해 이전 미션인 로또에서 부족했던 부분을 정리하여 이번 주차 미션에서 개선하려고 노력했다.

 

2번 피드백의 예외 상황을 모두 고려하여 프로그래밍하는 습관을 들이는 피드백에서 이전 주차 로또에서의 예외 상황의 예시를 주었다.

  • 로또 구입 금액에 1000 이하의 숫자를 입력
  • 당첨 번호에 중복된 숫자를 입력
  • 당첨번호에 1~45 범위를 벗어나는 숫자를 입력
  • 당첨 번호와 중복된 보너스 번호를 입력

 

첫 번째 예외 상황인 로또 구입 금액에 1000 이하의 숫자를 입력의 경우를 예외 처리를 해주지 못했다. 금액이 음수일 경우는 예외 처리를 해주었으나, 금액이 0일 경우의 예외 처리를 놓쳤다. 물론 0일 경우 0개의 로또를 구입해서 결과를 계산하여 버그가 발생하지는 않지만, 금액이 0이면 프로그램이 종료되거나 다시 입력받는 게 이상적이다.

따라서 이번 미션에서는 사용자의 입력에 대한 모든 예외 상황을 생각하여 프로그래밍하도록 했다.

 

10번 피드백의 테스트 코드도 코드다 라는 피드백에서 이전 미션에서 프로덕션 코드는 리팩터링을 많이 신경 썼지만, 테스트 코드에 대해서는 리팩토링을 신경 쓰지 못했다.

 

아래 접은 글들은 이전 미션인 로또 게임의 테스트 코드 중 일부이다.

각 테스트당 answer 로컬 변수가 중복된다. 이러한 부분은 테스트의 인스턴스 필드로 둬서 중복을 제거할 수 있었다.

 

각 테스트가 파라미터만 바뀌는 경우 @ParameterizedTest를 통해 중복을 제거할 수 있었다.

 

이번 주차 미션에서는 테스트 코드도 유지보수해야 하는 코드이기 때문에 중복을 제거하고, 깔끔하게 유지하기 위해 리팩토링에 더욱 신경썼다.

 

13번 피드백의 private 함수를 테스트하고 싶다면 클래스 분리를 고려한다. 이 부분은 이전 주차부터 디스커션을 통해 크루들? 과 해당 주제에 대해 토론했던 부분이다. 해당 주제에 대해서도 피드백을 들을 수 있었다.

 

부족했던 부분을 정리해 보자면,

  1. 모든 예외 상황을 고려하여 프로그래밍하도록 노력한다.
  2. 테스트 코드도 코드이기 때문에 중복을 제거한다.
  3. private 함수를 테스트하고 싶다면 클래스 분리를 고려한다.

 

 

2. 프리 코스를 TDD로 도전하면서 얻은 인사이트 정리

온보딩부터 목표했던 모든 프리코스 과정을 TDD로 성공적으로 마쳤다. TDD를 처음 해보는 거라 쉽지 않았지만, 미션 요구 사항을 지키려고 노력하고, TDD를 연습하며 문제를 작은 기능의 단위로 쪼개서 접근하는 방법, 단위 테스트 코드를 작성하는 방법, 클린 코드를 작성하는 방법, 객체지향적으로 코드를 작성하는 방법에 대해 배우고 역량을 끌어올리는 기회가 되었다.

 

미션을 통해 경험했던 TDD에 대한 인사이트를 간단하게 정리해 보았다.

  1. 디버깅 시간이 줄어드는 것은 확실하다.
  2. 테스트가 실패했을 때, 버그를 보다 빠르게 찾고, 효과적으로 개선할 수 있다.
  3. 버그 발생 가능성이 낮아, 좀 더 견고한 프로그래밍이 가능하다.
  4. 해당 도메인을 잘 이해할수록 TDD가 더 수월하다.
  5. 객체지향적인 사고, 문제 이해 역량에 따라 TDD 난이도가 달라질 수 있다.
  6. 기존의 개발 방법보다 시간이 더 오래 걸린다.(하지만 오히려 버그 발생 가능성이 줄어들어서 장기적으로 볼 땐 시간적인 면에도 장점이 있을 거라고 생각한다.)
  7. 완성한 기능에 대한 테스트 코드가 개발 중에 항상 존재하기 때문에 리팩터링 시에 두려움이 없다.(테스트를 통한 빠른 피드백을 통해 부담 없이, 버그 발생 가능성을 줄여 리팩토링 할 수 있다.)
  8. 해당 도메인에 대하여 객체지향적인 사고가 부족할 경우, TDD로 인해 더 나은 설계 방향으로 나아갈 수 있다. 
  9. 프레임워크나 많은 라이브러리가 의존되어 있을수록, 해당 개념이나 문법에 익숙지 않을수록, TDD가 쉽지 않다.
  10. TDD는 사이클 중에 테스트 코드를 작성하는 과정과, 리팩토링 하는 과정을 강제하여, 기능 구현만의 만족을 통한 개발자의 귀찮음과 나태함을 잡아줄 수 있다. (TDD를 하기 전에는 그냥 기능 구현하고 테스트 코드 작성하면 되는 거 아닌가? 에 대한 해답을 이번 주차에 찾을 수 있었다. 5분 전에 작성한 코드는 지금 당장 리팩터링 하기가 가장 쉽다!)

해당 내용에 대한 과정이 궁금하다면 이전 프리코스 회고록을 참고하면 된다.

 

TDD 앞으로의 도전!

TDD의 장점과 어떠한 경우에 힘든지 경험했다. 하지만 실전에서 활용하지 못한다면, 의미가 없다고 생각한다. 프리코스 과제에는 많은 프레임 워크나 라이브러리에 의존하지 않고, 애플리케이션 규모가 작고, 새로운 기능을 개발하기 때문에 TDD가 나름 수월했다고 생각한다.

 

하지만 현장에서는 그러지 않기 때문에 Spring 프레임워크에 대한 공부와 많은 연습이 필요한 것으로 생각한다. 하지만 Spring에 대한 깊은 이해와 학습이 부족하기에 아직 갈길이 멀다...🤣

 

 

3. 클래스를 분리하는 연습

이번 주차 목표 중 하나가 클래스를 분리하는 연습이다. 이번 주차는 주어진 클래스들을 이용하여 구현을 해야 했는데, 클래스들을 살펴보니 MVC 패턴을 활용하도록 의도하는 듯한 느낌을 받았다. Spring으로 개발해보면서 MVC를 많이 접했고, 이전 주차들도 MVC로 해왔기 때문에 구현하는데 어렵지는 않았다.

 

우테코 슬랙에서 어떤 분이  MVC를 주제로한 테코톡 유튜브 영상을 공유해주었다.(테코톡이란 우테코 본 과정에서 크루들이 한 가지 주제에 대해 발표하는 과정이다)

https://www.youtube.com/watch?v=ogaXW6KPc8I 

 

테코톡에서는 내가 알고있던 MVC 패턴과 상이했다. 따라서 구글링을 해봤는데, 여러 포스팅 글들도 MVC 패턴에 대해 상이하게 설명하고 있다. 내가 알고있던 MVC 패턴은 View가 Model을 의존하면 안되는데, 해당 테코톡 영상이나 몇몇 포스터들은 View가 Model을 의존하는 경우가 있었다. 너무 혼란스러웠다.

 

따라서 나는 공식 문서를 찾아보았고, 애플의 MVC 문서를 통해서 답을 찾을 수 있었다.

 

Model-View-Controller

Model-View-Controller The Model-View-Controller design pattern (MVC) is quite old. Variations of it have been around at least since the early days of Smalltalk. It is a high-level pattern in that it concerns itself with the global architecture of an applic

developer.apple.com

많은 사람들이 서로 다른 MVC 패턴에 대해 얘기하고 있는 이유는 기존의 Original MVC와 애플에서 변형한 Cocoa MVC가 존재했고, 서로 본인들이 먼저 접한 다른 MVC에 대해서 말하고 있기 때문이었다. View 조차도 Model을 의존하지 않는 Cocoa MVC가 내가 기존에 알고 있던 MVC와 비슷했다. 

 

이러한 차이를 모르 채 본인이 접했던 MVC에 대해서만 아는 사람도 있을 거고, 나처럼 혼란스러운 사람도 있을 것으로 생각한다. 따라서 미션을 완료하고, 해당 애플 문서를 통해서 서로 상이한 두 MVC 패턴의 차이와 특징에 대해서 정리하여 프리코스 디스커션에 공유하려고 한다.

 

만약 프리코스가 아니었다면, MVC 패턴에 대해 깊게 생각해보고, 찾아보지 않았을뿐더러, 나도 이러한 차이를 계속 몰랐을 것이다.

 

 

4. 도메인 로직에 대한 단위 테스트를 작성하는 연습

3주 차 피드백에 "단위 테스트하기 어려운 코드를 단위 테스트 하기"라는 피드백이 있었다. 랜덤 값에 관한 이야기인데 어떤 클래스가 랜덤 값에 의존하고 있으면, 랜덤 값은 예측하지 못하는 값이기 때문에 테스트하기가 어려운 구조이다.

 

하지만 도메인 로직에 대한 단위 테스트를 작성해야 하므로 나는 이전 주차까지는 랜덤 값에 대한 의존을 역전하여 해당 도메인 클래스가 랜덤 값을 주입받는 식으로 설계하여 단위 테스트를 했었다.

 

이번 다리 건너기 미션에도 도메인 로직에서 랜덤 값을 의존하는 부분이 있었는데, 미션을 주어질 때부터 랜덤 값을 인터페이스로 추상화하여 랜덤 값을 생성하는 클래스를 제공해주었다. 왜 굳이 인터페이스를 만들어서 추상화를 하였는지 생각해보았다.

 

해당 인터페이스를 의존하는 코드를 살펴보니 주어진 인터페이스를 구현한 테스트용 구현체를 따로 만들어서 해당 클래스와 이후 로직들을 테스트할 수 있겠다라는 생각이 들었다.

 

따라서 테스트 패키지 하위에 주어진 함수형 인터페이스를 구현하여, 테스트를 위한 클래스를 생성하였다. 이후 단위 테스트하기 어려운 도메인 로직을 쉽게 테스트 할 수 있었다.

 

또한 이러한 클래스 설계 구조의 장점을 생각해보았다. 이후 건널 수 있는 다리의 위치가 늘어나서(현재는 U, D만 가능) 다른 종류의 다리를 만들어야 하는 요구사항이 생기고 기존의 다리를 만드는 경우를 유지해야 한다면, 이러한 설계는 해당 인터페이스를 통해 구현한 새로운 구현체를 바꿔 끼워서 유연하게 대처할 수 있는 장점이 있다. 마치 테스트를 위한 구현체를 바꿔 끼워서 테스트한 것처럼 말이다.

 

이번 프리코스를 통해서 테스트 코드를 제대로 작성하는 방법뿐만 아니라 테스트하기 어려운 코드를 테스트하기 쉬운 구조로 바꾸는 방법을 간접 경험했다.

 

정리해보자면 다음과 같다,

  1. 테스트 하기 어려운 메서드의 접근 제어자를 변경하여 테스트 코드에서 해당 메서드를 오버라이드 하여 테스트한다.(하지만 3주 차 피드백에서 테스트를 위해 접근 제어자를 바꾸지 말라고 되어있어서 좋은 방법은 아닌 듯하다.)
  2. 테스트하기 어려운 부분의 의존성을 역전하여 주입 받는 식으로 구조를 설계한다.
  3. 테스트 하기 어려운 부분을 인터페이스로 추상화하여 테스트를 위한 구현체를 구현하여 활용한다.

 

 

5. 프리코스 커뮤니티(아고라) 참여

아고라 질문 글 중 기능 단위 커밋에 대한 커밋 범위를 어떻게 잡으시나요? 의 주제에 대한 의견을 공유하였다.

 

 

6. 프리코스 커뮤니티 (피어 리뷰)를 통해 느낀 점

3주 차에 진행한 미션에 대해 코드 리뷰를 받을 수 있었고, 나 또한 다른 사람의 코드를 리뷰해주었다.

 

이번 주차에는 세 분에게 리뷰를 받았고, 두 분에게 리뷰를 해주었다.

 

이번 피어 리뷰를 하면서 서로의 의견을 주고받으면서 토론 한 부분이 있다. 

"상태(인스턴스 변수)를 가지지 않는 클래스들의 경우는 model 패키지 보다는 service 패키지가 더 어울리지 않냐"는 의견이었다.

나는 비지니스의 주요 로직이라고 생각해서 상태를 가지지 않는 클래스들을 model에 두었다. 실제 웹 서비스였다면 해당 클래스들도 데이터를 저장하고 관리하기 위해 상태를 가졌을 것으로 생각했기 때문이었다. 하지만 지금은 웹 애플리케이션이 아니기 때문에 지금은 service 패키지에 더 어울린 다는 생각이 들었다.

 

피어 리뷰가 아니었다면 이러한 의견을 받을 수도 없었을 거고, 생각해보지도 못했을 거다. 해당 의견을 주고받은 후 아키텍처에 대해서도 공부해야겠다는 생각이 들었다. 피어 리뷰를 통해 서로의 의견을 공유하고 이야기하는 것이 단순 지식의 얻음 뿐만 아니라 나에게 어떠한 공부가 필요한지의 방향에 대해서도 도움이 되었다.

 

 

7. 마무리

"결과에 후회하지 않도록 최선을 다하자"

 

지금까지 제출한 미션 목록이다. 결과를 보니 뿌듯하다.😊

프리코스는 끝났지만, 프리코스를 진행하면서 읽고 싶은 책이 많아져서 연말에는 책을 많이 읽으면서 시간을 보내려고 한다. 읽고 싶은 책은 이펙티브 자바, 클린 코드, 객체지향의 사실과 오해, 오브젝트, 클린 아키텍쳐이다.(언제 다 읽지..?)

공유하기

facebook twitter kakaoTalk kakaostory naver band