3주 차는 가장 급했지만, 그래도 여태까지 작성한 코드들 중 가장 좋은 코드를 짰다.
이렇게 될 수 있었던 이유는 힘들었지만 내가 우테코 과정을 재밌게 즐기면서 잘 노력했기 때문이라고 생각한다.
이번 주차는 특히 당연한 걸 당연하지 않게 생각하는 것에서 큰 성과를 이루었다고 생각한다.
물론 아쉬운 점도 존재하긴 하지만 4주 차도 잘 준비해서 유종의 미를 맺었으면 좋겠다.
(3주 차는 4주 차 과제가 너무 어려워 시간이 필요해 블로그를 빠르게 작성하려고 한다.. 블로그도 나중에 리팩토링,,,)
목표설정
이번 주차의 목표는 퇴고였다.
새로운 것을 잘하기 보단, 기존에 잘하고 있던 것이나 피드백으로 주어진 것들을 잘 지키며 하고 있는지를 중점으로 생각하며 코드를 작성했던 것 같다.
우테코에선 매번 새로운 것을 배우다 보니 바로바로 적용하는 것이 쉽지 않았다.
특히 2주 차에 Jest를 사용할 때는 가장 기본적인 기능들만 사용해서 급하게 작성해서 해당 주차의 목표를 잘 달성하지 못했다.
이런 것 처럼 이번 주차에는 당연하게 쓰던 README나 아키텍처, 컨벤션 등 다시 되짚어보는 시간을 가지게 되었다.
공통 피드백
3주 차쯤 되니까 피드백이 가볍지 않고 묵직하게 날아오는 느낌을 받았다.
과연 일정을 관리하면서 어디까지 반영할 수 있을지는 스스로와의 싸움이지만 4주 차도 열심히 해봐야겠다!
- 함수(메서드) 라인에 대한 기준도 적용한다
- 함수, 클래스 분리를 잘해야한다.
- 불필요한 공백, bracket은 줄인다.
- 가독성과 유지보수성을 높인다.
- 예외 상황에 대한 고민한다
- 정상적인 상황 외에도 예외 상황도 테스트를 잘 한다.
- 비즈니스 로직과 UI 로직의 분리한다
- 이 말의 의미는 다음과 같다.
- 기능을 담당하는 로직과 UI 로직을 한 파일 내에서 관리하지 않는다.
- UI 로직에 데이터가 필요하다면 getter 매서드를 통해 전달 받는다.
- 객체의 상태 접근을 제한한다
- private 연산자를 사용한다.
- 이런 방식의 장점은 다음과 같다.
- 비즈니스 규칙 준수 보장
- 버그 발생 가능성 감소
- 코드의 의도가 명확해짐
- 테스트가 용이해짐
- 향후 변경에 유연하게 대응 가능
- 객체는 객체답게 사용한다
- 객체 외부에서 값을 재구성 하지 말고 객체가 자신의 데이터를 스스로 처리하도록 한다.
- 필드(인스턴스 변수)의 수를 줄이기 위해 노력한다
- 정보는 많이 담는 다고 좋은게 아니다.
- 성공하는 케이스 뿐만 아니라 예외 케이스도 테스트한다.
- 예외 케이스의 범주를 잘 생각한다.
- 테스트 코드도 코드다
- Jest를 잘 익혀서 테스트 코드도 이쁘게 짜라.
- 테스트를 위한 코드는 구현 코드에서 분리되어야 한다
- 테스트를 위한 코드는 좀 분리해둬라.
- 단위 테스트하기 어려운 코드를 단위 테스트하기
- 확장성을 고려해서 코드를 짜라
- 불확실한 데이터는 의존성을 분리하거나 주입을 통해, 객체가 관리 되기 쉽도록 한다.
고민했던 부분
1. README 잘 작성하고 있나?
잘하는 사람들의 README를 근거 없이 참고해서 작성하다 보니, 어느샌가 나도 읽기 싫은 REAEME가 되어있었다.
README는 내 프로젝트를 타인에게 보여주는 얼굴인 만큼 쉽고 이해하기 쉽게 작성해야겠다고 생각했다.
또한 어느샌가 README 작성에 시간을 엄청 뺏기고 있다는 것을 깨달았다.
내가 나중에 최종 테스트에선 5시간 안에 모든 것을 해야 하는데 과연 이 많은 README를 잘할 수 있을까?라는 생각이 들었다.
그래서 README도 컨벤션을 만들어야겠구나!라고 생각했다.
3주 차의 README도 사실 크게 잘 작성하진 못했는데 4주 차 때는 더 나은 README를 작성할 수 있도록 해야겠다.
2. 아키텍처에 대한 고민
이번 3주 차에서도 뭔가 어떠한 아키텍처를 써야지! 하고 코딩을 시작한 건 아니었는데 막상 코드를 다 짜고 보니 MVC 패턴에 기반한 코드가 되어 있었다.
처음 3주 차의 아키텍처를 짤 때 내용 중 "도메인에 대한 단위 테스트를 진행한다"라는 내용이 있어서 도메인과 아키텍처에 대해서 고민하다가 2022 우아콘에서 발표된 아키텍처 관련 발표를 보게 되었는데, 이게 좋은 아키텍처에 대한 생각이구나라는 것을 알게 되었다.
아키텍처에 대한 생각을 하는데 큰 도움이 되었고 학문을 조금 더 공부해야겠다는 생각이 들었다.
3. 의존성 주입
// 1.
constructor() {
const LottoController = new LottoController();
}
// 2.
constructor() {
this.#lottoController = new LottoController();
}
후자의 방식이 더 좋은 방식인데 이유는 다음과 같다.
- 캡슐화
- private 필드(#)를 사용하여 외부에서 직접 접근/수정을 막을 수 있음
- 클래스 내부에서만 controller를 다룰 수 있게 됨
- 클래스 멤버로서의 명확성
- constructor에서 초기화함으로써 이 컨트롤러가 클래스의 필수적인 부분임을 명시
- 다른 메서드에서도 this를 통해 컨트롤러에 접근 가능
- 생명주기 관리
- 인스턴스의 생명주기가 App 클래스의 생명주기와 함께 관리됨
- 메모리 관리 측면에서도 더 예측 가능
여태까지 MVC 패턴을 짜면서 전자의 방식을 사용했는데 이번엔 다음과 같이 후자를 사용했다.
controller만 private로 선언해서 받아온 뒤에 필요한 부분의 의존성 주입으로 넣었다.
의존성 주입을 사용한 이유는 리뷰에서 이미 남겨서 이미지로 남겨둔다.
4. 상수 컨벤션
상수 관리에 대한 고민을 하다가 Airbnb 컨벤션을 확인하니 내가 잘못 쓰고 있다는 사실을 알게 되었다.
마침 2주 차 공통 피드백에서 "값을 하드코딩하지 않는다"라는 말이 있기도 해서 바로 사용해 보았다.
// bad - unnecessarily uppercases key while adding no semantic value
export const MAPPING = {
KEY: 'value'
};
// good
export const MAPPING = {
key: 'value',
};
Airbnb 컨벤션에 따르면, 아래와 같이 키는 대문자, 값은 소문자로 작성한다고 한다.
다만 이 방식이 의미론 적이긴 하지만 가독성에 있어서는 큰 장점이 있는지 모르겠다.
5. 함수 & 변수 네이밍
이번 주차에서 가장 어려웠던 부분이었다.
다음과 같이 invalid로 통일해서 컨벤션을 맞추려고도 하였고 한 단어를 사용해서 의미를 내포하려고도 해 봤는데.. 명확하게 통일을 하지 못했다. 나중에는 오히려 통일을 하려고 했다는 게 잘 못된 생각이 아니었을까..라는 생각도 들었다.
함수에 관해서도 처음엔 isValidXXX라고 이름을 지었다가 결과가 false라면 if문에서 ! not 연산자를 다 달아줘야 하니까 너무 별로 인 것 같았다. 나는 throw Error를 하기 위해 해당 함수를 사용했기에 false가 더 자주 사용되어서 isInvalid로 명칭을 바꾸게 되었다.
나는 이런 서사를 알고 있으니까 좋긴 한데, 처음 코드를 읽는 사람이 보기엔 불편하지 않을까 라는 생각이 들었다.
6. 요구사항
요구사항의 문자열 처리 중 다음과 같은 내용이 있었다.
코드를 다 짜고 리팩토링을 할때 케이스들을 보고 있었는데 1,000,000.0%
를 보니 3자리마다 콤마가 박혀있는 것을 확인했다.
나는 해당 부분에 대해서 처음에 toFixed(1)
로 처리를 했었는데, 해당 부분을 보고 다음과 같이 코드를 고쳤다.
toLocalString
을 사용하면 반올림과 콤마 모두 해결할 수 있어서 다음과 같이 작성을 했다.
그런데 리뷰를 해드리면서 보니 다들 toFixed
로 되어 있어서 내가 너무 과몰입했나..? 라는 생각도 들긴 했다.
회고를 마치며
앞서 말했듯이 3주 차 회고는 4주 차를 위해 조금 짧게 쓰려고 한다.
아직 리뷰에 대한 답변도 마저 다 못했다..
잠깐 리뷰에 대한 답을 했는데 거의 대부분이 네이밍에 관한 피드백이었다!
다음번엔 네이밍을 조금 더 공들여서 해야겠다는 생각이 들었다.
3주 차가 스스로에게 엄청 힘든 주차였는데, 회사도 다니고 이렇게 힘들게 살아야 하나? 행복에 기준이 뭐지? 등등 여러 의문들이 꼬리를 물었다.
금, 토, 일을 다 우테코 하는데 쏟았는데 힘들었지만 꽤나 즐거웠다.
진짜 개발이 좀 천직이 맞는 것 같다는 생각이 들었다.
마무리는 3주 차 과제 제출할 때 작성했던 소감문의 일부로 하려고 한다.
이번 미션이 저에게는 정말 힘들었습니다.
그 과정에서 "내가 왜 이렇게 힘들게 우테코를 하고 있는거지?"라는 생각을 곱씹어 보면서, 왜 개발자가 되고 싶은지 곰곰이 생각해 보게 되었습니다.
세상에는 개발 말고도 돈을 벌 수 있는 수단은 많다고 생각합니다.
버그 터지면 스트레스받고 머리 아픈 일투성인데 "왜 굳이 개발이어야 하는가?" 라고 스스로에게 물어봤을때, "즐거우니까" 라는 답변을 할 수 있는 일은 저에겐 개발밖에 없는 것 같습니다.
이번 3주 차 미션을 하는 데 있어서 일정을 여유롭게 잡지 못했습니다.
그래서 쉴 틈 없이 피드백을 반영하고 모자란 부분을 채우기 위해 노력했고 공부했습니다.
빠르게 개발을 해서 프로토타입을 만들어도 모자란 시간에 고민을 했습니다. "이 아키텍처는 현재 미션에 적합할까? 아키텍처란 뭘까?" 꼬리에 꼬리를 무는 의문들이 생겨나갔고 공부를 하면 할수록 시간은 모자라져 쉬지도 못하고 공부하고 코딩을 해야 했습니다.
왜 개발보다 고민을 많이 했냐면, 저는 우테코를 하면서 "내가 알아보기 위한 코드가 아닌 타인을 위한 코드를 짜는 법"을 공부하고 있다고 느꼈기 때문입니다.
주 차를 거치면서 정답이 없는 아키텍처에 기준을 잡기 위해 많은 어려움이 있었습니다.
굳이 패턴이나 구조를 분리할 필요도 없이 미션을 통과 하기 위함이라면 App.js에서만 코드를 작성해도 부족하지 않다고 생각했습니다.
하지만 "왜 굳이 패턴을 사용하고 역할을 분리해야할까?"라고 고민하다 보니 "좋은 아키텍처란 무엇일까?"라는 의문점이 생겼습니다.
아키텍처를 잘 활용하면 유지보수를 쉽게 할 수 있다는 장점도 있지만 결국 "왜 유지보수하기 쉽게 코드를 작성해야 하는가?" 라고 생각을 하니 "서비스와 같이 일하는 개발자를 위해서" 라는 결론에 도달 했습니다.
내가 알아보기 위한 코드 였다면 고민할 필요 없이 이미 알고 있는 개념으로 코딩했어도 미션을 통과하는데에는 큰 문제 없었을 겁니다.
하지만 우테코에서 페어 프로그래밍을 하다보니 점점 정답은 없지만 내가 왜 이 코드를 짜야했는지에 대한 근거가 필요 했습니다.
그 근거를 만들기 위해 다양한 자료들을 찾아 봐야 했고 상대방이 알아보기 좋은 코드로 짜야하니 "좋은 코드란 무엇인가?"로 이어진 것 같습니다.
이런 생각을 하면서 코드를 짜다보니 점점 더 근거있는 코드를 작성하게 되었고, 이번 주차가 가장 시간적으로 촉박 했음에도 가장 만족스러운 코드를 짤 수 있었던 것 같습니다.
'Programming' 카테고리의 다른 글
[우테코 프리코스/7기] 프리코스 최종 코딩테스트 후기 (36) | 2024.12.17 |
---|---|
[우테코 프리코스/7기] 프리코스 2주 차 회고 (1) | 2024.11.02 |
[우테코 프리코스/7기] 프리코스 1주 차 회고 (4) | 2024.10.24 |
[우테코 프리코스/7기] 커밋 방식 알아보기 (4) | 2024.10.16 |
[우테코 프리코스/7기] 본격적인 시작 전 준비 (0) | 2024.10.15 |