[우아한테크코스] 2주차 과제 코드 리뷰 돌아보기
많은 분들께서 정성스럽게 코드리뷰를 남겨주셨다.
가지고 계신 지식을 링크까지 첨부해가며 공유해주시고, 칭찬도 아끼지 않는 모습에 너무 감사했고 감동도 많이 받았다.
나도 그들에게 그런 사람이 될 수 있도록 조금 더 코드 리뷰를 진심과 지식(?)을 가득담아 해야겠다고 생각했다.
Reviewer로 배운 것
1. Jest에서 beforeEach() 활용
2. Input Validation Class를 만들어놓고, 유효성 검사 함수를 InputView에 Callback으로 전달해주는 방법
3. Class Private field (#)
4. import를 index.js로 한번에 하는 방법 알아보기
5. trim() 적절하게 사용하는 방법
6. PR에 Object Diagram 활용
7. Error Msg에도 매직넘버를 상수화 하여 작성 하는 방법
(Ref : https://github.com/woowacourse-precourse/javascript-racingcar-7/pull/257)
const VALIDATION_ERROR_MESSAGE = Object.freeze({
INCLUDE_EMPTY_SPACE:
'[ERROR] 입력값 중 빈 문자열 혹은 공란이 포함되어있습니다.',
IS_NOT_POSITIVE_INTEGER: '[ERROR] 입력값은 양의 정수값이 아닙니다.',
GAME_ATTEMPT_OUT_OF_RANGE: `[ERROR] 게임 시도 횟수는 ${GAME_ATTEMPT_RANGE.MIN}이상 ${GAME_ATTEMPT_RANGE.MAX}이하의 자연수만 가능합니다.`,
NAME_LENGTH_OUT_OF_RANGE: `[ERROR] 참가자 이름은 ${NAME_LENGTH_RANGE.MIN}자 이상 ${NAME_LENGTH_RANGE.MAX}자 이하만 가능합니다.`,
PARTICIPANT_COUNT_OUT_OF_RANGE: `[ERROR] 참가자는 ${PARTICIPANT_COUNT_RANGE.MIN}명 이상 ${PARTICIPANT_COUNT_RANGE.MAX}명 이하만 가능합니다.`,
INVALID_NAME_FORMAT:
'[ERROR] 참가자 이름은 영문 대소문자, 숫자, 하이픈("_"), 언더스코어("_")만 포함해야합니다.',
DUPLICATED_NAME: '[ERROR] 중복된 이름이 입력되었습니다.',
});
8. for-of 사용을 지양하고, forEach(), reduce() 사용
9. Controller가 Model과 View의 흐름만 제어하고 있음. 이게 좋은 구조인 듯.
- 나는 Controller가 Model의 일을 좀 한 것 같음. (Game진행)
Reviewee 로 배운 것
Keep
- magic number를 지양함
- README.md에 예외상황을 표로 도식화 하여 상세히 작성했음 → 한눈에 들어온다고 함
- test.each() 를 사용하여 반복되는 test 기능을 파라미터화 한 것
- 파라미터화가 무엇인가? 고민하다가 동적파라미터화 라는 내용에 빠짐. 나중에 적절하게 써먹어 봐야지.
Problem
1. 큰 고민없이 쓴 empty 유효성 검사

- 구글링에 isEmpty 검색해서 별 고민없이 작성했다. ‘undefined’ 자체가 문자로 들어오는 경우도 있을까? 어떤 경우가 있을까?
- JSON 파일에서 값이 “undefined”로 오는 경우가 있나보다.
- 근데 stringify로 test해보면 undefined는 무시 된다. null도 따옴표 떼고 저장이 된다.
- 따로 JSON에도 ‘undefined’가 문자로 표시된다는 사전 협의가 없는 이상 ‘undefined’ 문자열 empty 처리는 해주지 않아도 될 것이라 결론내렸다.
2. airbnb 컨벤션 - 객체이름은 대문자, key와 value는 camelCase로 작성한다.
23.10 상수 이름을 대문자로 짓는 것은 해당 상수가 (1) 내보내기 될 때, (2) const 타입일 때 (값이 재할당되지 못할 때), (3) 그 상수와 상수가 중첩된 속성이 절대 변하지 않는다는 것을 신뢰할 수 있을 때만 하세요.
왜? 이것은 변수가 영원히 변하지 않는다는 것을 확신할 수 없을 때 도움을 주기 위한 추가적인 도구입니다. 대문자 변수는 변수와 변수의 속성이 변하지 않는다는 것을 프로그래머에게 알려줍니다.
- 모든 const 변수 이름을 대문자로 짓나요? - 이것은 필수사항이 아니며, 파일 내 상수 이름을 꼭 대문자로 지을 필요는 없습니다. 하지만 내보내기되는 상수 이름은 대문자로 지어야 합니다
// bad
const PRIVATE_VARIABLE = 'should not be unnecessarily uppercased within a file';
// bad
export const THING_TO_BE_CHANGED = 'should obviously not be uppercased';
// bad
export let REASSIGNABLE_VARIABLE = 'do not use let with uppercase variables';
// ---
// allowed but does not supply semantic value
export const apiKey = 'SOMEKEY';
// better in most cases
export const API_KEY = 'SOMEKEY';
// bad - unnecessarily uppercases key while adding no semantic value
export const MAPPING = {
KEY: 'value'
};
// good
export const MAPPING = {
key: 'value'
};
3. 생각만 해 놓고 써먹지 않은 dead code들

4. 해쉬 # 접두사로 Class 멤버를 private으로 설정하는 방법 (링크)
6. 유효성 검사에 대한 토론

- 유효성 검사 시점을 각 기능의 책임별로 분리를 해봤다. 시점에 대한 고민은 어느정도 마무리가 되었는데
- 유효성 검사를 하는 방식들이 굉장히 다양했다. 각 방법들마다 장단점이 어떤건지 잘 모르겠다.
이번 기회를 빌어 파헤쳐보아야 겠다.- Class 내부 / Validator Class / 콜백함수
7. 책임은 분리하되, 에러처리 지점을 앞당길 수는 없을까?
내 코드에서는 게임 횟수까지 입력받은 뒤에 자동차 이름에 대한 유효성을 검사한다.
그러면 hamo님이 말씀하신 것 처럼 잘못된 자동차 이름이 입력되었음에도 불구하고, 실행 횟수까지 입력했을 때 에러가 발생하게된다. 이부분은 고민이 필요할 것같다.

8. Class Naming : MVC 패턴을 적용하려다보니 Class 이름도 Model, Controller같은게 되어야한다고 생각했다. 사실 별 고민없이 지었다. 클래스의 기능이 드러나는 구체적인 모델의 이름으로 작성했다면 더 좋았을 것 같다.
9. 매직넘버를 에러메세지에 써먹어보기 (링크) ’거북이’님 리뷰에 에러메세지 내에 있는 매직넘버로 상수처리를 해놓은 걸 보고 좋은 방법이라고 생각했다. 나도 3주차때 써먹어봐야지.

10. 뇌를 빼놓고 코딩한 순간들

11. MVC를 왜 적용하셨나요?
: 사실은 다들 쓰길래 쓴거였다. 근데 쓰다보니 내가 쓴 댓글처럼 책임이 잘 분리가 되는 마법이 벌어졌다. 다양한 패턴들을 학습하고 사례에 익숙해지며, 프로그램 기능에 찰떡처럼 들어맞는 패턴을 잘 적용하는 내공을 쌓아야겠다고 생각했다.

프리코스 2주차 공통 피드백
어제의 나와 오늘의 나를 비교하며 성장해라. 다른 사람과 비교하면 조바심이 나기 마련이다.
회고의 중요성 (우테코 5기 한달 생활기 링크)
회고를 통해 우리는 학습과 경험을 그냥 지나치지 않고 반성하고 개선할 수 있다.
7.
나는 어떤 개발자가 되고 싶을까. 매일 아침 여덟 시부터 밤 열한 시까지 무얼 위해 공부를 하고 있을까. 너른 집을 놔두고, 세 평 남짓한 달방에서 왜 쭈그려 새우잠을 청할까. 가족, 강아지, 친구가 아른거려도 왜 그리워만 하고 있을까.
8.
세상이 조금 더 아름답기를 바란다. 각자가 안전하게 자아를 실현해서, 다양한 웃음과 노래가 흘러넘쳤으면 한다. 내가 만든 서비스가 이러한 세상을 만드는 데에 도움이 되고 싶다.
9.
밤 열한 시의 귀갓길은 항상 오백오십오미터의 롯데타워가 배웅을 해준다. 방에서 볼 때는 꽤나 만만한데, 루터회관 앞에서는 정말 하늘 높은 줄 모르겠다. 캠퍼스에서는 꿈도 타워처럼 크고 엎어지면 닿을 것처럼 보인다. 그래서 매일같이 출근을 한다.
타워 바로 앞 잠실역 입구에는 로또 1등이 십 수 차례나 나온 소위 ‘명당’이 있다. 그 앞으로 길게 늘어선 인생의 무게들을 마주할 때면 금세 또다시 태풍이 인다. 아직 철이 덜 들어서 꿈을 좇는 건가 싶다. 나침반이 또 요동치면, 다시, 눈을 꼭 감고 속으로 되뇐다.
작아진 건 방 크기로 충분하고, 줄어든 건 사랑하는 이들과의 만남으로 족하다.
10.
나는 우아한테크코스를 믿지 않는다.
정확히는, 우아한테크코스가 꿈을 이루어 줄 것이라고 믿지 않는다.
다만 각자의 꿈을 위해 서로 도우며 성장하는, 함께 우아한테크코스를 만들어가는 사람들을 믿는다.
그리고, 그들 덕분에 결국 이뤄낼 내 꿈을 믿는다.
요즘, 참 오랜만에 콧노래를 흥얼거린다.
이 글을 보고 큰 울림을 받았다.
프리코스 기간 동안 '무엇을 위한 열심'인가? 계속 나에게 질문하며 주춤거리고 자꾸만 뒤를 돌아보면 내 모습이 부끄러웠다.
나는 사람들에게 따뜻함을 나눠주고 싶다.
서로가 가진것을 베풀었을 때, 베풀면서 잃는 것이 아니라 얻는 것이 더 많아질 때 느껴지는 따뜻함과 충만함을 느끼고싶다.
사실 남을 위한 일인 것 같지만 나를 위한 일이다.
그걸 이루기 위한 수단으로 나는 개발을 선택했다.
마음만 가지고선 이룰순 없다.
도움을 주기 위해선, 가진 걸 베풀기 위해선 먼저 '가져야한다'
그래서 나는 이렇게 공부를 하고있다.
README.md 상세하게 작성하기
- 프로젝트의 개요를 소개하는 문서
- 해당 프로젝트가 어떤 프로젝트인지, 주요 기능이 무엇인지 소개한다.
- 마크다운 문법에 익숙해지고 효과적인 문서를 작성해본다.
기능 목록 재검토
- 기능 목록을 작성할 때 클래스 설계와 구현, 메서드 설계와 구현 같은 상세한 내용은 포함하지 않는다. 클래스 이름이나 메서드 시그니처, 반환값 등은 언제든지 변경될 수 있기 때문이다.
- 구현해야 할 기능 목록을 중심으로 작성하되, 정상적인 경우뿐만 아니라 예외 상황도 함께 정리한다.
- 예외 상황은 시작 단계에서 파악하기 어려우므로, 기능을 구현하면서 지속적으로 업데이트하는 것이 좋다.
- 기능 목록을 업데이트한다.
값 상수화
- 구글에 "javascript const" 등의 키워드로 검색하여 상수 구현 방법을 학습하고 코드에 적용해 본다.
구현 순서
- 필드, 생성자, 메서드 순으로 Class를 작성한다.
메서드가 한 가지 기능을 하는지 확인하는 기준을 세운다
여러 메서드에서 중복되는 코드가 있다면 이를 별도 메서드로 분리하는 것을 고려한다.
메서드의 길이가 길어지면 여러 기능을 포함하고 있을 가능성이 커지므로, 15라인이 넘지 않도록 구현하면 의식적으로 메서드를 분리하는 연습을 할 수 있다.
테스트를 작성하는 이유에 대해 본인의 경험을 토대로 정리해본다
테스트를 작성하면 기능의 정확성을 점검함을 넘어 코드의 즉각적인 피드백을 받을 수 있다.
테스트 작성 과정을 통해 구현한 기능의 문제를 빠르게 발견할 수 있을 뿐만 아니라, 코드의 구조와 의도를 명확히 이해하는 데도 도움을 받을 수 있다.
학습 도구로도 활용할 수 있는데, 수 많은 테스트의 장점 중 본인이 가장 공감하는 작성 이유를 작성해 본다.
테스트의 장점
- 프로그램 요구 사항의 이해도가 높아진다.
- 코드가 변경되어도 항상 동일한 수준의 기능을 보장할 수 있는 지표가 된다.
- 단위 테스트를 잘 작성해두면 프로그램의 오류 위치가 명확하게 드러날 것 같다. 디버깅에 쏟는 시간이 줄어든다.
- 내 프로그램이 어디까지 테스트 되었는지 타인에게 알릴 수 있는 지표가 된다. 커버리티
이 중 가장 공감하는 작성이유는 하… 다 좋은데…
프리코스에서는 프로그램 요구 사항의 이해도가 높아지고, 코드의 구조와 의도를 명확히 이해하는데 된다는 주장에 가장 공감이 간다.
처음부터 큰 단위의 테스트를 만들지 않는다
테스트의 핵심 목적 중 하나는 코드에 대해 빠르고 자주 피드백을 받는 것이다. 처음부터 큰 단위의 테스트를 작성하게 되면, 작성한 코드의 문제를 발견하기까지 시간이 오래 걸린다. 따라서 문제를 작게 나누어 핵심 기능부터 작게 테스트를 만들어 가는 것이 효과적이다.
큰 단위의 테스트
- 자동차 경주 게임을 시작하여, 사용자가 이름과 진행 횟수를 입력하고, 게임을 진행한 후 결과를 확인한다.
작은 단위의 테스트
- 무작위 값이 4 이상이면 자동차가 전진한다.
- 무작위 값이 3 이하이면 자동차가 전진하지 않는다