새오의 개발 기록

우테코 5기 프리코스: 3주차 회고 본문

우테코 프리코스

우테코 5기 프리코스: 3주차 회고

새오: 2022. 11. 17. 15:07

 

고난의 3주 차도 막을 내렸습니다..!

이번 미션은 고려해야 할 부분들이 정말 많았는데요 익숙하지 않은 개념들이 많아서 어떻게든 기능 구현이라도 해내자는 생각으로 버텨냈어요! 포기하지 않은 나 자신 대견합니다....ㅎ 프리코스를 통해 성장하는 부분이 정말 많지만 아무래도 마냥 즐겁게 참여할 수만은 없는 게 우테코 선발 과정에 포함되기 때문인 것 같아요. 그래도 코수타에서 코치님이 결과를 목표로 하지 말고 과정을 목표로 하자는 생각을 가지라는 조언을 해주신 게 3주의 프리코스로 지쳐가던 제 심신에 큰 위로가 되었어요. 4주 차까지 프리코스의 과정을 온전하게 경험하는 것을 목표로 삼아야겠어요.

 

4주차 미션도 얼른 시작해야 하기 때문에 과제 제출에 남겼던 소감문과 3주 차 피드백을 보면서 4주 차 미션에서 목표로 할 내용을 정리해보는 방식으로 회고를 작성해야겠습니다. 회고 포맷이 3주 내내 다 다르네요..ㅎ 아직 회고 작성 경험이 많지 않아서 제게 맞는 방법을 찾아가고 있는 것 같아요. 각설하고 회고록을 작성해보겠습니다..!

 

 

 

 

 

 

3주 차 미션 진행 과정

 

 

문제 설명

 

3주 차에는 로또 게임을 구현하는 미션이 주어졌습니다.

클래스로 구성된 Lotto.js를 활용하여 구현해야 했는데 클래스를 js에서 사용해본 적이 없어서 문제가 제한하는 사항을 이해하는데도 한참이 걸렸어요..

스피또는 많이 해봤는데 복권은 거의 해본 적이 없어서 규칙도 찾아보고 테스트 코드 작성까지 처음부터 끝까지 어려움이 단계별로 찾아왔던 미션이었습니다 ㅎ

 

 

 

GitHub - woowacourse-precourse/javascript-lotto: 로또 미션을 진행하는 저장소

로또 미션을 진행하는 저장소. Contribute to woowacourse-precourse/javascript-lotto development by creating an account on GitHub.

github.com

 

 

 

3주 차 미션 주요 이슈 사항

 

  • 클래스 사용
  • 비동기 코드 테스트

(아래 소감문에 자세히 작성했음)

 

 

 

 

 

 

 

3주차를 마치고

 

이번 주차에서 부족했던 개념을 제대로 짚고 4주 차 미션을 시작하는 게 좋을 것 같아 시간이 빠듯하게 느껴집니다. 이번 주 공통 피드백도 정말 개인 피드백과 다름없이 제가 고민했던 부분이 고스란히 담겨있네요...ㅎ 정말 피가 되고 살이 되는 피드백 같아요...!!!!! 4주 차를 앞두고 걱정이 많았는데 공통 피드백만 잘 반영해도 3주 차보다는 훨씬 발전된 코드를 작성할 수 있을 것 같은 자신감이 막 차오릅니다 ㅎㅎ 의욕 상실 직전이었는데 너무 감동적인 피드백이에요...💟 이것부터 반영해보고 여유가 된다면 피어 리뷰도 참여해봐야겠습니다! 

 

 

 

 

3주 차 공통 피드백

 

함수(메서드) 라인에 대한 기준 

프로그래밍 요구사항을 보면 함수 15라인으로 제안하는 요구사항이 있다. 이때 공백 라인도 한 라인에 해당한다. 15라인이 넘어간다면 함수 분리를 위한 고민을 한다.

 

 

어렵습니다 눈물 나게 어려워요...💦

 


 

발생할 수 있는 예외상황에 대해 고민한다.

정상적인 경우를 구현하는 것보다 예외 상황을 모두 고려해 프로그래밍하는 것이 더 어렵다. 예외 상황을 고려해 프로그래밍하는 습관을 들인다. 예를 들어 로또 미션의 경우 아래와 같은 예외 상황을 고민해 보고 해당 예외에 대해 처리를 할 수 있어야 한다.

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

 

1,2,3 주차 모두 예외 상황에 대한 고민은 잘하고 있는 것 같아 뿌듯합니다 💟

 

 


 

비즈니스 로직과 UI 로직을 분리한다.

비즈니스 로직과 UI 로직을 한 클래스가 담당하지 않도록 한다. 단일 책임의 원칙에도 위배된다.

 


 

객체의 상태 접근을 제한한다.

필드는 private class 필드로 구현한다.객체의 상태를 외부에서 직접 접근하는 방식을 최소화하는 이유에 대해서는 스스로 찾아본다.

 

 


 

🌟🌟🌟 객체는 객체스럽게 사용한다.

 

 

 

Lotto 클래스는 Numbers를 상태 값으로 가진다.

그런데 이 객체는 로직에 대한 구현은 하나도 없고, numbers에 대한 getter 메서드만을 가진다.

 

 

Lotto에서 데이터를 꺼내지(get)말고 메시지를 던지도록 구조를 바꿔 데이터를 가지는 객체가 일치하도록 한다.

 

 

 

 

getter를 사용하는 대신 객체에 메시지를 보내자

getter는 멤버변수의 값을 호출하는 메소드이고, setter는 멤버변수의 값을 변경시키는 메소드이다. 자바 빈 설계 규약에 따르면 자바 빈 클래스 설계 시, 클래스의 멤버변수의 접근제어자는 private

tecoble.techcourse.co.kr

 


 

필드의 수를 줄이기 위해 노력한다

필드의 수가 많은 것은 객체의 복잡도를 높이고, 버그 발생 가능성을 높일 수 있다. 필드에 중복이 있거나, 불필요한 필드가 없는지 확인해 필드의 수를 최소화한다. 예를 들어 총 상금 및 수익률을 구하는 다음 객체를 보자.

 

위 객체의 profitRate와 totalPrize는 등수 별 당첨 내역(result)만 있어도 모두 구할 수 있는 값이다.

 

따라서 위 객체는 다음과 같이 하나의 필드만으로 구현할 수 있다.

 

솔직히 클래스를 사용해야 하는 이유를 잘 모르겠었는데 어렵지만 클래스의 매력을 알아가는 것 같아요 💟

 

 


 

성공하는 케이스 뿐만 아니라 예외에 대한 케이스도 테스트한다

테스트를 작성하면 성공하는 케이스에 대해서만 고민하는 경우가 있다. 하지만 예외에 대한 부분 또한 처리해야 한다. 특히 프로그램에서 결함이 자주 발생하는 부분 중 하나는 경곗값이므로 이 부분을 꼼꼼하게 확인해야 한다.

 

 

 


테스트 코드도 코드다

테스트 코드도 코드이므로 리팩터링을 통해 개선해나가야 한다. 특히 반복적으로 하는 부분을 중복되지 않게 만들어야 한다.

예를 들어 파라미터의 값만 바뀌는 경우라면 아래와 같이 테스트할 수 있다.

 

 

예시 완전 꿀팁 💟

 


테스트를 위한 코드는 구현 코드에서 분리되어야 한다

테스트를 위한 편의 메서드를 구현 코드에 구현하지 마라. 아래의 예시처럼 테스트를 통과하기 위해 구현코드를 변경하거나 테스트에서만 사용되는 로직을 만들지 않는다.

 

  • 테스트를 위해 #prefix를 바꾸는 경우
  • 테스트 코드에서만 사용되는 메서드

단위 테스트하기 어려운 코드를 단위 테스트하기

 

 

아래 코드는 Random때문에 Lotto에 대한 단위 테스트를 하기 힘들다.

단위 테스트가 가능하도록 리팩터링한다면 어떻게 하는 것이 좋을까?

 

 

올바른 로또 번호가 생성되는 것을 테스트하기 어렵다.

테스트하기 어려운 것을 클래스 내부가 아닌 외부로 분리하는 시도를 해 본다.

 

위 코드는 A 상황을 B로 바꾼 것이다.

 

 

 

이처럼 단위 테스트를 할 때 테스트하기 어려운 부분은 분리하고 테스트 가능한 부분을 단위 테스트한다. 

테스트하기 어려운 부분은 단위 테스트하지 않아도 된다.

남은 LottoMachine은 어떻게 테스트하기 쉽게 바꿀 수 있을지 고민해본다.

 

 

 

 

메서드 시그니처를 수정하여 테스트하기 좋은 메서드로 만들기

tecoble.techcourse.co.kr

 

 

 

 

 

 

소감문

 

더보기

3주차에 중요하게 생각한 미션은 클래스 사용, 기능 분리, 상수화, 그리고 테스트 코드 작성이다. 미션에서 주어진 Lotto 클래스를 활용해 구현하라는 요구사항이 있었는데 클래스를 거의 사용해본 적이 없었기 때문에 문제 이해부터 어려움을 겪었다. 필드를 추가할 수 없다는 말이 어느 범위를 의미하는지도 이해하지 못했고 붕어빵 틀 사례로만 이론적으로 이해하고 있었는데 실전에서 쓰려니 적용이 되지 않아 막막했다. 클래스를 사용하는 이유부터 찾아보았는데 직관적으로 쉽게 코드를 읽을 수 있게 만들어 준다는 내용이 가장 와닿아서 이를 중점으로 클래스를 구현해보기로 했다. 주어진 Lotto 클래스의 private filed를 왜 private으로 사용하는지에 대해서부터 한참을 고민했는데 당첨 번호이니까 함부로 변경되지 않아야 한다는 결론을 내렸다. 이를 확장해서 보너스 번호와 당첨 번호를 관리하는 winningLotto 클래스를 만들려고 시도했는데 제대로 동작하지 않아 결국 따로 만들 수밖에 없었다. 작성한 기능 목록을 기준으로 로또를 생성하는 클래스와 로또의 결과를 산출하는 클래스를 만들었고 이게 테스트를 구현해야 할 도메인 기능이라고 정의했다. 클래스 안에 여러 메소드가 들어가게 되고, 이 부분까지 클래스로 분리해야 하는지를 고민했는데 클래스 명을 LottoGenerator, LottoCalculator로 지었기 때문에 그 안에 포함되는 내용은 클래스 내부에 속하게 하자고 생각했다. 한편으로는 이름을 기준으로 기능을 생각하게 되는 걸 보면서 네이밍이 이래서 중요하구나 싶기도 했다. 클래스를 이번에 온전히 사용하지는 못했지만 최소한 앞으로의 개발에서 클래스화에 대한 발상을 할 수 있을 것 같고 하게 적용을 시도해볼 것 같다. 이를 위해서 객체 지향에 관한 공부를 더 해봐야겠다.

이전 미션과 달리 이번에는 상수도 분리했는데 같은 의미의 값이 중복으로 사용되어 하나의 상숫값으로 관리하는 것이 효율적이거나 값의 의미가 분명하게 전달되지 않다면 상수로 분리하였다. 에러 메시지의 경우 상수화했을 때 오히려 코드의 의미를 파악하기 어려운 것이 아닌가 고민되기도 했는데 중복되는 에러가 있어 분리하였다. 이 부분은 앞으로 개발하면서도 매직넘버라고 무조건 상수화하기 전에 어떤 방향이 더 효율적이고 직관적으로 의미가 전달될지 고민이 필요한 부분인 것 같다. 그래도 저번 미션에서 출력 기능에 상수화되지 않은 부분들까지 더해져 복잡했던 기능에 비하면 많이 개선된 것 같다.

사실 클래스를 사용해서 기능 구현을 하는 것 자체에 많은 시간을 쏟아 테스트 코드에 비교적 적은 부분을 쓴 것 같다. 그리고 비동기 코드로 작성한 부분이 테스트가 제대로 되지 않아 코드를 수정해야 했던 부분에서 테스트 코드를 위해 코드를 수정하는 게 맞는 건가 하는 의문이 들었다. jest를 비동기 식으로 테스트하는 방법도 있다고 하는데 진행하고 있는 토이 프로젝트에서 꼭 적용해보려고 한다. 전반적인 미션의 완성도는 이전 미션들에 비해 아쉬움이 남지만 그만큼 새로 적용해보는 개념들이 많아 고민하는 시간이 많았는데 왜 이렇게 구현하는지, 어떻게 구현할 건지 계속 논리적으로 사고하면서 개발적 사고력이 키워지는 것 같다. 또 지금까지 자바스크립트 언어를 얼마나 제한적으로 써왔는지도 깨닫고 있다. 이번 미션에서 고민해본 것들을 계속 적용해보고, 또 그 고민을 확장해가면서 역량을 키우고 싶다. 얻어가는 것이 정말 많은 한 주였다.