
11분 코드 리뷰하고, 리뷰 답변 및 정리하고,
미션 구현하고, 관련 개념 학습하다,
소감문 쓰고, 제출하니
어느새 3주 차 시작이 다가왔다..!
더 나은 한 주를 위해 회고해보자!!!
이번 주 목표
2주 차 목표는 공통 피드백 및 코드 리뷰를 통해 배운 점을 미션에 적용해 보는 것이다!
코드 리뷰를 통해 혼자 고민하면서 놓쳤던 부분을 학습하고,
나와는 다른 시각으로 미션을 구현한 코드를 보며 사고의 폭을 확장하고 싶다.
이를 통해 여러 사람과의 소통 속에서 다양한 인사이트를 얻는 것을 이번 주의 핵심 목표로 삼았다.
10/21 ~ 22 (화, 수) Day 1, 2
오늘의 도전
- 근거 또는 이유를 가지고서 총 10명 코드 리뷰 남기기
- 코드 리뷰 하면서 얻은 피드백 정리
- 커밋 스코프 기준 및 범위 토론하기
1. 코드 리뷰
코드 리뷰 하는데 시간이 생각보다 오래걸렸다. 한 분당 적어도 40분 ~ 1시간,,,?씩 총 10분의 코드를 리뷰하다 보니 이틀이 금세 지나갔다.
그래도 그만큼 다른 사람들의 코드를 보며 얻은 인사이트가 정말 많았다.
새로운 관점에서 접근하는 방식이나, 내 코드의 개선점을 발견하면서 많이 배울 수 있었다.
구분자 추출을 위해 정규식을 활용할 수 있다던가, 커스텀 구분자 비교를 위해 전략패턴을 활용하는 등 내가 미처 떠올리지 못했던 다양한 구현 방식을 접했다.
일주일 동안 미션을 구현할 때는 떠오르지 않았던 방법인데,, 코드 리뷰를 통해 다른 사람들의 접근 방식을 보며 내 사고의 폭이 확장되는 느낌이라 즐거웠다!!
또 나랑 비슷한 고민을 하신 분들도 많았지만, 내가 전혀 고려하지 않았던 부분을 깊이 고민하신 분도 계셨다.
System.exit()를 사용금지하는 요구 사항을 보고 왜 사용하면 안되는지 main 함수 종료 흐름을 깊게 파보았다던가,
정규식을 캐싱해야 하는 이유를 깊이 분석하신 분도 있었다.
나아가 입력에 대한 코드를 작성할 때 NoSuchElementException 예외를 무시 해둔 것을 본 적이 있는데,
디스코드 함께 자라기 채널을 통해 그 이유를 파악할 수 있었다.
실제 환경에서는 빈문자열이 입력값으로 들어올 수 없고, 이로 인해 NoSuchElementException 예외가 발생할 수 없기 때문이다.
(자세한 내용은 `""` 테스트가 실패하는 이유와 Scanner의 `NoSuchElementException` 참고!)
나는 그동안 그런 내용을 보며 단순히 “아~ 그런가보다” 하고 넘어갔는데,
딥다이브 하시는 분들의 자세를 보며 ‘이렇게 깊게 파고드는 자세를 나도 배워야겠다' 고 느꼈다.

2. 코드 리뷰 피드백 정리
다른 분들의 코드 리뷰를 마친 뒤, 이번에는 내가 받은 피드백을 다시 돌아보며 답글을 달고 정리하는 시간을 가졌다.
제출할 때는 최선의 코드를 제출했는데, 피드백을 받으니 고칠 부분이 많이 보였다😅
이에 2주 차 미션에 들어가기 앞서, 2주 차에 반영해볼 피드백을 정리하였다.
이 과정에서 도메인, 상수 등 그동안 ‘어렴풋이 알고 있다’고 생각했던 개념들을 다시 되짚으며, 확실한 기준을 세울 수 있었다.
또한 객체마다의 책임을 좀 더 작게 부여해야겠다는 점을 느꼈다.
크게 깨달은 건,,,
커뮤니티와 코드 리뷰를 통해 서로의 의견을 나누다 보면,
혼자서는 인지하지 못했던 문제를 발견하고 새로운 해결책의 실마리를 찾을 수 있다는 것이다.
이런 경험이 정말 값졌다.
우아한테크코스에 합류하게 된다면, 이런 토론과 피드백의 과정을 매일 반복하면서 함께 그리고 빠르게 성장할 수 있을 것 같은데!!
그래서 더더욱, 꼭 합격하고 싶다는 마음이 들었던 것 같다.
피드백을 통해 얻은 내용은 아래 글에 따로 정리하였다!
https://jiihyunn.tistory.com/30
우아한테크코스 프리코스 - 1주 차 피드백 정리
들어가며2주 차 미션 시작에 앞서!!1주 차 미션(문자열 덧셈 계산기) 코드리뷰를 하며 얻은 리뷰 및 인사이트를이번 미션에 반영해보고 싶어 피드백을 정리해보았다.이번 리뷰에서는 도메인의
jiihyunn.tistory.com
3. 커밋 스코프 기준 및 범위 토론하기
1주 차에 AngularJS Commit Conventions를 학습하며 의미 있는 커밋 메시지 작성의 중요성을 배웠다.
AngularJS에서는 커밋 스코프가 존재하며, 선택적으로 적용할 수 있다고 써있다.
이에 커밋 스코프를 활용하는 것이 좋을지, 활용한다면 어떤 기준 및 범위를 가지고 활용하면 좋을지 고민을 많이 했다.
1주 차에는 스코프를 model, view, controller처럼 코드의 계층 단위로 표현 했지만, 이 방식이 과연 적절한가에 대한 확신은 들지 않았다.
그래서 혼자만의 판단에 머무르지 않고, 다른 사람들의 의견을 들어보기로 했다.

2주 차 미션을 들어가기 전 ‘커밋 스코프 사용하시나요? 사용하신다면 어떤 기준으로 설정하시나요?’라는 주제로 커뮤니티에 토론글을 올렸다.
커밋 스코프를 사용하는지, 사용한다면 어떤 기준으로, 어떤 단위로 스코프를 표현하는지? 또, 그렇게 사용하면서 얻은 장점이나 불편했던 점이 있었다면 듣고 싶었다.
토론에서는 각자 다른 기준과 경험이 오갔다. 어떤 크루는 도메인 단위로 스코프를 설정해 커밋의 변경 지점을 직관적으로 드러내는 방식을 사용하고 있었고, 또 다른 크루는 클래스나 메서드 단위로 세밀한 표현을 통해 명확성을 높이는 방식을 선호했다.
반면 일부 크루는 스코프 자체를 생략하고 메시지 본문만으로도 충분히 의도를 전달할 수 있다는 의견을 제시하기도 했다.
이 다양한 의견을 듣는 과정에서, 나는 스코프를 세밀하게 구분하는 대신 헤더 타입과 메시지 내용으로 의도를 전달하는 방식이 더 실용적이라는 의견에 공감했다.
실제로 1주 차에 스코프를 적용해 보았을 때, 스코프 범위가 넓어 직관적으로 느껴지지 않았고 스코프 사용한 효과를 크게 체감하지 못했고, 오히려 스코프를 확인하기 전에 커밋 메세지와 file changed만으로도 충분히 커밋 변경 내역을 파악할 수 있었기 때문이다.
이러한 경험과 토론을 통해, 스코프를 표시하는 것보다는 의도가 명확하게 드러나는 커밋 메세지를 작성하는 것이 더 중요하다고 느꼈다.
따라서 이번 주차부터는 스코프를 생략하고 헤더 타입과 메시지 중심으로 커밋을 구성하는 방식을 시도해 보고자 한다.
무엇보다 인상 깊었던 점은, 내 고민이 다른 크루들의 고민과 닿아 있었다는 사실이었다.
괜히 나만 사소한 부분에 매몰된 건 아닐까 싶었는데, 비슷한 고민을 하신 분들이 계셔서 반가웠다.
서로의 접근 방식을 공유하면서 내가 몰랐던 관점을 배우기도 했고, 반대로 내가 올린 토론 주제가 비슷한 고민을 하고 있던 분들께 도움이 되었다해서 기뻤다.
따라서 앞으로도 서로 공부한 내용들 공유하고 그것을 바탕으로 토론하면서 함께 성장하는 경험을 많이 해야겠다고 다짐했다.
10/23 (목) Day 3
오늘의 도전
- 기능 구현 시 AI 사용하지 않기
- 2주 차 설계 및 기능 목록 작성
- 도메인 클래스 구현하기
1. 기능 목록 작성
1주 차와 동일하게 프로그램 흐름 → 요구사항 → 명세화 → 설계 순으로 미션에 대해 이해하면서 기능 목록을 작성했다.
설계를 진행하면서 느꼈던 건 객체마다 책임을 부여할 수는 있어도, 객체 간의 협력 관계를 떠올리기가 쉽지 않았다는 것이다.
어떤 객체가 어떤 메시지를 보내고, 누가 그 요청을 받아서 어떻게 응답해야 할지를 구체적으로 설계하는 과정이 특히 어려웠다.
그래서 일단은 내가 생각할 수 있는 선까지 최대한 설계하고, 실제로 코드를 작성하면서 자연스럽게 구조를 다듬는 방향으로 진행하기로 했다. 구현하다보면 코드가 눈에 보이니까 어떻게 협력시켜야 할 지 파악할 수 있지 않을까..?ㅎㅎㅎ
앞으로 협력 중심으로 객체를 설계하는 사고방식을 어떻게 기를 수 있을지도 고민해봐야겠다.


2. 도메인 객체 생성
자동차들을 움직이기 전에, 움직일 때 필요한 도메인 객체들을 먼저 구현하였다.
1주 차 미션 때 구분자를 enum으로 등록했다가 VO로 만들었어도 좋을 것 같다라는 리뷰를 받았다.
그게 머릿속에 남아서 이번엔 VO에 대해 다시 학습해보고 직접 적용해보기로 했다.
이번 미션에서는 Name과 Round를 VO로 분리했다.
Round는 게임의 진행 단계를 표현하는 값이었는데,
“마지막 라운드인지 판단한다.”, “라운드의 값은 범위 내에 존재해야 한다.” 같은 규칙이 존재했다.
이 규칙들이 도메인의 의미를 강화한다고 느껴서, Round를 VO로 분리했다.
그 결과, 라운드라는 개념이 코드상에서도 명확히 드러나고, 관련 규칙이 한곳에 응집되어 코드의 의도가 훨씬 선명해졌다.
이 과정을 통해 “왜 VO를 써야 하는가”를 실감할 수 있었다.
반면, position은 같은 패턴을 적용할 필요가 있을지 고민이 됐다.
처음엔 일관성을 위해 Position도 VO로 만드는 게 자연스러워 보였지만, 실제로는 그 필요성이 명확하지 않았다.
position은 단순히 “자동차가 이동한 거리”를 나타내는 값으로,
독립적인 규칙이나 의미가 있는 별도의 도메인 개념은 아니었다.
캡슐화를 위해 VO로 감싸는 걸 고려했지만,
이미 Car 내부에서 position을 완전히 제어하고 있어서 추가적인 이점은 없다고 판단했다.
오히려 불필요한 객체만 늘어나서 코드 복잡도만 높아질 것 같았다.
그래서 position은 VO로 만들지 않기로 했다.
이번 과정을 통해 모든 값을 VO로 만드는 게 좋은 건 아니라는 걸 느꼈다.
VO를 사용할 때는 단순히 불변성을 확보하기 위함이 아니라,
값의 의미를 명확히 전달하고, 관련된 검증이나 계산 로직을 캡슐화할 필요가 있을 때 사용하는 게 진짜 이유라는 걸 배웠다.
복습 겸 짧게 요약하자면
VO의 사용 이유는 값에 대한 명확한 의미 전달과 갑과 관련된 검증 및 계산 로직 캡슐화이며,
VO를 사용할 떄는 반드시 불변성과 값 동등성을 챙기기로 하자!!
10/24 (금) Day 4
오늘의 도전
- 미션 구현 완료하기
1. static 메서드 사용 기준 확립
1주 차 코드 리뷰를 통해 도메인이 무엇인지에 대한 기준을 명확히 세우면서, 자연스럽게 static 메서드를 언제 써야 할지에 대한 기준도 확립할 수 있었다.
이전까지만 해도 막연히 “객체지향 설계를 위해 static은 피하자!”라고만 생각했었다.
하지만 도메인의 경계를 명확히 하다 보니, 반대로 비즈니스 규칙과 직접적인 연관이 없고,
상태를 가지지 않으며, 여러 클래스에서 공통으로 사용할 수 있는 로직이라면
오히려 static 메서드로 두는 게 더 깔끔하다는 걸 깨달았다.
1주 차에는 이런 기준이 없어서, 하나의 클래스 안에 유틸성 로직과 도메인 로직이 섞여 있었다.
비즈니스 규칙을 검증하는 로직과 단순히 문자열을 파싱하는 기능이 같은 클래스 안에 들어 있었기 때문에
정적 멤버로 분리할 수 없었다.
이번에는 리뷰를 통해 깨달은 점을 코드에 반영하고자
단순히 문자열을 파싱하거나 숫자를 변환하는 기능처럼
비즈니스 규칙과 직접적인 연관이 없는 유틸성 로직들은 별도의 Parser 클래스로 분리했다.
이렇게 역할을 분리하니 Parser는
- 상태를 가지지 않고,
- 여러 도메인에서 공통으로 사용할 수 있으며,
- 비즈니스 규칙과도 직접적인 관련이 없는
정적 멤버 객체의 조건을 자연스럽게 충족하게 되었다.
이전에는 “도메인”이라는 말이 막연하게 느껴졌는데,
이제는 어떤 코드가 비즈니스 의미를 표현하고, 어떤 코드는 단순히 동작을 돕는 유틸에 속하는지 스스로 판단할 수 있는 기준이 생겼다.
덕분에 코드의 책임이 훨씬 명확해졌고, 나만의 기준이 생겨서 뿌듯함을 느꼈다!
2. move()메서드 테스트 실패
나는 TDD까지는 아니더라도,,기능을 구현하고 해당 기능에 대한 테스트를 작성한 뒤,
기능을 올바르게 구현했는지에 대한 피드백을 받는 흐름으로 개발을 진행했다.
미션 요구사항으로 자동차 전진조건을 랜덤값에 의해 판단해야 했는데
이 랜덤 값 때문에 테스트 코드에서 예상할 수 있는 결과를 얻기 어려웠다.
실행할 때마다 값이 달라지다 보니, 어떤 경우엔 통과하고 어떤 경우엔 실패하는 등 결과가 일관되지 않았고,
이로 인해 의미 있는 테스트 코드를 작성하기 어려웠다...
이 때, 1주 차 코드 리뷰에서 봤던 전략 패턴이 떠올라서, 자동차 이동과 관련한 책임을 인터페이스로 분리해보려 했지만 1차 실패했다!!!
책임 분리는 어찌저찌해서 자동차 이동 조건과 이동 전략에 대한 인터페이스를 생성했지만,
이 책임들을 어디서 협력시킬지 모르겠고, 어떤 매개변수와 어떤 타입을 반환시켜야 할지 모르겠었다.
그래서 이런저런 클래스 생성해보고 반환타입 바꿔가면서 여러 시도를 했지만 맘에 드는 코드는 작성하지 못했다.
일단은 테스트 없이 넘어가고,,,내일 맑은 정신으로 조금 더 고민해보고 리팩토링 해보는 걸로!!
10/25 (토) Day 5
오늘의 도전
- 자동차 전진시키는 기능 테스트 코드 작성하기
- 리팩토링 및 추가 테스트코드 작성
1. 랜덤 값에 의존하는 전진 기능 테스트 하기
처음에는 자동차가 이동할지 말지를 결정하는 ‘이동 전략’ 자체를 인터페이스화해야 한다고 생각했다.
하지만 요구사항에 나와있는 책임들을 다시 세세하게 나누다보니 인터페이스가 필요한 부분은 ‘이동 여부를 판단하기 위해 필요한 숫자 생성 로직’에 있음을 깨달았다.
내가 구현하고 싶었던 건 항상 움직이거나 항상 멈추는 전략이 아니라,
생성된 숫자에 따라 움직임이 달라지는 구조였다.
따라서 이동 전략이 아니라 숫자 생성 부분을 유연하게 바꾸면 충분했다.
그래서 숫자 생성 과정을 추상화하기 위해 NumberGenerator 인터페이스를 도입했다.
이를 통해 실행 시에는 랜덤 숫자를 반환하는 RandomNumberGenerator를,
테스트 시에는 고정된 숫자를 반환하는 FixedNumberGenerator를 사용할 수 있게 했다.
이렇게 하니 프로그램은 랜덤성을 유지하면서도 테스트에서는 원하는 결과를 쉽게 제어할 수 있었다.
이번 설계를 통해 인터페이스가 주는 확장성을 체감할 수 있었다.
조건을 바꾸고 싶을 때마다 if문을 추가하거나 기존 코드를 수정할 필요 없이,
새로운 구현체를 만들어 주입하는 것만으로도 다양한 상황을 쉽게 추가할 수 있음을 경험했기 때문이다.
확장성을 위해 인터페이스 어떻게 활용할 수 있을지 조금은 느낄 수 있었던 경험이었다!
2. 리팩토링
기능 구현시 놓쳤던 테스트 케이스들을 작성하면서 코드를 전반적으로 돌아보았다.
은근히 실수가 많더라,,ㅎㅋ
1주 차 코드 리뷰에서 피드백받았던 불변 컬렉션 적용도 아직 익숙하지 않아 놓쳤고,
무엇보다 미션 요구사항 중 하나였던 랜덤 번호 범위를 0~9가 아닌 1~9로 설정한 실수도 발견했다.
요구사항 및 작성한 코드를 수시로 점검하는 습관을 가져야겠다!!!!!!!
10/26 (일) Day 6
오늘의 도전
- 리팩토링 최최종
1. record, 너! 불변 아니였어?
자동차 이동 결과를 전달하기 위해 DTO를 만들 때 record를 사용했다.
record는 모든 필드가 final로 선언되니까, 컬렉션도 자연스럽게 불변일 거라 생각했다.
하지만 dto에서 컬렉션을 꺼내어 리스트를 직접 수정해보니, 생각이 완전히 틀렸다는 걸 깨달았다.
record의 필드가 final이더라도 참조만 고정될 뿐, 내부 리스트의 원소는 여전히 변경 가능했다.
이 문제를 해결하기 위해 생성자 안에서 List.copyOf()를 사용해 컬렉션을 한 번 더 감싸 불변 컬렉션으로 만들어주었다.
그 결과, 외부에서 리스트를 변경하려 해도 예외가 발생하도록 안전하게 보호할 수 있었다.
코드 리뷰에서 배운 List.copyOf()를 직접 부딪혀보며 체득할 수 있어 재밌었고, 오래 기억에 남을 것 같은 경험이었다!
10/27 (월) Day 7
1주 차때와 마찬가지로 하루종일 소감문만 작성하였으니,,패스-!
느낀점
2주 차가 시작되고 부터 생각보다 많은 시간을 코드 리뷰와 피드백 정리에 쏟아야 했다.
특히 코드 리뷰는 10명이 넘는 분들의 코드를 읽게 될 줄은 정말 몰랐다 😅
다양한 코드 스타일을 보면서 많이 배웠지만, 스스로 아쉬웠던 점도 있었다.
가장 아쉬웠던 건 리뷰 과정의 티키타카가 부족했다는 점이다.
한 번 리뷰를 남기고 나면, 다시 확인하거나 대화를 이어가기엔
다른 분들의 리뷰도 해야 하고 미션도 진행해야 해서 마음이 조급했다.
결국 깊은 대화보다는 단발성으로 리뷰를 주고 끝난 것 같다.
그래서 이번 미션부터는 방향을 바꿔 리뷰 할 사람 수를 줄이고, 더 깊이 있는 피드백을 주고받는 것에 집중하기로 했다.
7명-8명으로 리뷰 인원을 좁히고, 대신 코드를 더 깊이 읽고 의미있는 리뷰를 주고받는 과정에서 서로 성장할 수 있도록 노력하기로!!
또한 미션 구현 시작을 예상보다 늦게 시작해서 계속 마음이 조급했다.
그래서 하루하루 핵심 키워드 정도만 짧게 메모해두고, 회고는 제대로 하지 못한 채 넘어간 날이 많았다.
따라서 이번 주는 저번보다 더 열심히 회고해서 미션이 끝난 다음 날(+1일) 까지는 꼭 회고 올리는 걸 목표로 삼을 생각이다.
마지막으로 미션 진행하다가 새로 알게 된 지식에 대해 딥다이브 해보는 것을 목표로 설정하며 마무리 하겠다.
여러 이벤트가 겹쳐서 더 정신없었던 2주 차인데,,, 회고해보니 나름 많이 고민하고 성장한 것 같다!
3주 차도 잘 보내봐야지~!~!~!
ㄲㅡㅅ!
'Reflection' 카테고리의 다른 글
| 우아한테크코스 8기 최종 코딩테스트 회고 (4) | 2026.01.19 |
|---|---|
| 우아한테크코스 프리코스 - 3주 차 회고 (0) | 2025.11.04 |
| 우아한테크코스 프리코스 - 1주 차 피드백 정리 (0) | 2025.10.23 |
| 우아한테크코스 프리코스 - 1주 차 회고 (0) | 2025.10.21 |
| 우아한테크코스 재도전에 앞서 (2) | 2025.10.13 |