우테코 프리코스 3주차 회고

버건디·2023년 11월 13일
0

우테코

목록 보기
3/8
post-thumbnail

과제 원본 레포

내 PR

🔍 1. 객체가 그 자체로 동작하도록 하자

이번 미션 중, 입력 받은 당첨 번호를 WinningLotto 클래스로 주입하기 위해 getNumbers()라는 메서드를 사용하게 되었다.

getNumbers()라는 인스턴스 메서드를 통해 값만 가져오는것은 상태 값을 변경하는것이 아니고 이어서 캡슐화 원칙에 어긋나지 않으니까 괜찮지 않을까? 라는 생각을 했었다.

하지만 완성을 하고 보니, WinningLotto 클래스 자체에서 해당 당첨 번호를 받아오도록 하고 그안에서 동작하도록 하는것이 낫지 않을까? 라는 의구심이 들었.

또한 디스코드 커뮤니티에서 get 함수를 지양해야한다는 말이 있었는데, 이러한 부분도 get함수를 지양해야한다는 부분에 해당하는 부분인지 궁금했.

그렇게 하면 더 낮은 결합도를 가지게 되고 응집도는 높일 수 있을 것이라 판단했.

이런 저런 리팩토링을 거쳐보면서, 뭐가 더 나은 방법인지 혼란스러웠다.

코드리뷰를 진행하면서 감사하게도 리뷰어분이 조언을 해주셨다.

🔍 2. 테스트 코드에서 각 도메인 간의 의존성

당첨 통계에 관한 테스트 코드를 작성하는 중에, 각 모델들간의 의존성 분리를 고민해 볼 수 있었다.

가령 당첨 통계를 담당하는 Reward의 생성자에는 당첨 번호와 보너스 번호를 담당하는 WinningLotto 클래스가 필요했고, 또 WinningLotto 클래스에선 Lotto 클래스에서부터 나온 값이 필요했기에,

Reward 클래스에 대한 단위테스트를 진행하기 위해선 모든 클래스에 대한 인스턴스를 만들어주어야했다.

은닉화라는 이유로 해당 인스턴스 값을 클래수 내부에서 get 함수를 통해 가져와서 그랬던것이었는데, 아예 값 자체를 1번처럼 외부에서 주입해줌으로써 각 도메인간 의존도를 줄일 수 있었다.

🔍 3. 예외 처리 후 다시 입력값 받기 (함수의 재사용성)

이전 과제들과는 다르게 이번에는 예외 처리 후에 그 값부터 다시 입력값을 받도록 하는 조건이 추가되었다.

이 부분에 대해서 처음에는 각 입력값을 받는 함수마다 while - try - catch 문을 사용해서 오류가 해결 될때까지 while 문이 반복 되도록 했다.

하지만 각 함수마다 try - catch가 반복 되는 가독성 문제와 while 문에서 무한루프 오류가 발생할 수도 있겠다고 판단했다.

이를 해결하기 위해 asyncFnHandlerWithError 라는 유틸 함수를 만들어서 반복문이 아니라 재귀적으로 작동하도록 했습니다.

결과적으로 재사용성과 코드 가독성을 높힐 수 있었다.

- 코드 예시

const asyncFnHandlerWithError = async (asyncFn, context) => {
  try {
    return await asyncFn.call(context);
  } catch (error) {
    // 에러 메세지 출력
    return asyncFnHandlerWithError(asyncFn, context);
  }
};

export default asyncFnHandlerWithError;

🔍 4. 테스트를 작성하는 이유에 대해 본인의 경험을 토대로 정리해본다.

이번 2주차 공통 피드백중에 위의 항목이 있었는데, 사실 메일을 받은 직후까지만 해도 이 사항이 크게 와닿지 못했다.

사실 지금까지 테스트 코드를 한번도 제대로 작성해본적이 없었다.

테스트 코드 작성하는 법은 알아야해! 라는 말은 여러번 들었었지만, 이 사항이 지금까지 개발을 해오면서 크게 와닿았던적이 없었기에 소홀해왔었다.

하지만 이번에 프리코스, 특히 이번 3주차를 통해서 테스트 코드 작성의 필요성을 여실히 느꼈다.

내가 느낀 테스트 코드 작성의 필요성은 크게 3가지로 나누어 볼 수 있다.

  • 설계 개선
    위의 2번 항목과 연결이 되는 부분이다.
    테스트 코드를 작성해보면서 각 도메인 클래스들간의 의존성 분리를 고민해 볼수 있었기에, 더 나은 설계 구조를 갖게 되었다.

  • 문서화 기능
    통계 결과를 담당하는 Reward 클래스 같은 경우 통계 결과를 출력 하기 위한 메서드만 총 9개였다.
    그렇기에 코드를 처음 접했을땐 한번에 각각 메서드의 의도를 파악하기 힘들것이라고 생각했다.
    하지만 RewardTest.js 에서 해당 클래스에 대한 단위 테스트 코드를 작성하면서 각각 메서드들이 어떠한 동작을 해야하는지에 대해 남들이 봤을때도 이해에 도움이 될 수 있는 명세서를 작성 할 수 있었다.

  • 오류 감지
    단위 테스트를 작성한 후 전체적인 진행을 담당하는 테스트 코드를 작성했는데, 예상한 값과는 다르게 오류가 나왔었다.
    당첨 통계 계산에 대한 오류였고, 이 테스트 코드를 작성해보지 않았다면 파악하지 못하고 지나갔을 오류였다.
    이를 통해서 다양한 테스트 케이스들을 주입해보면서 단순히 테스트만 하는것이 아니라 어플리케이션의 완성도를 더 견고히 할 수 있음을 깨달았다.

🔍 5. 클래스 다이어그램 작성 (리드미의 중요성)

프리코스를 진행하면서 가장 성장 하고 있다고 느끼는 부분이 디테일적인 부분이다.

가령 함수의 분리라던지, 깃 컨벤션 등이 있다.

리드미 작성를 작성하는 것 또한 나에게는 이 디테일적인 부분이 성장했다고 느껴지게 하는 부분이다.

리드미 작성을 통해서 나만의 기능 명세서를 작성해보고, 기능 구현을 정리해 볼수 있었다.

또한 file-generator-tree라는 익스텐션을 통해 폴더 구조를 정리해서 첨부해볼 수 있었습니다.

이러한 디테일적인 부분을 더욱 더 보완해보고 싶다는 욕심이 들었습니다.

그리하여 이번에 draw.io 라는 사이트에서 클래스에 관한 다이어그램을 생성해서 리드미에 첨부할 수 있었다.

이를 통해서 단순히 폴더 구조가 아니라, 각 클래스의 의존성, 또한 클래스 내에 존재하는 메서드들을 담은 명세서를 작성할 수 있었다.

🔍 6. 깊은 동결

자바스크립트는 객체에 접근해서 쉽게 값을 추가, 변경 할수 있기 때문에 과제에서 사용되는 진행 메세지라던지, 변하지 않는 값들을 Object.freeze()를 사용해서 상수화를 했었다.

하지만 MDN에서 freeze()에 관한 내용을 살펴 보다가 이 또한 완전한 상수화를 해주지 못한다는 내용을 보았고 deepFreeze라는 유틸 함수를 알게 되었다.

재귀적으로 freeze()를 작동하게 해서 완전히 동결 시켜주어 상수에 대해 값 변경, 추가, 삭제도 실행되지 않도록 하는 것이었다.

그래서 이번 미션에선 deepFreeze()를 사용하여 상수의 무결성을 보장해줄 수 있었다.

이와 관련하여 작성한 글

🔍 7. 돌아가는 쓰레기를 만드는것의 중요성과 능동성 기르기

저번주 목요일날 우테코 디스코드에서 5기분들과의 코수타를 진행 했었을때 참여했었다.

사전 질문으로, 5기분들에게 우테코에 들어와서 가장 성장하고 바뀌었다고 느끼는 점에 대해서 여쭈어보았었다.

그 질문에 대해서 "개발을 하면서 프로젝트를 하기전에 완벽주의 비슷하게 빠져서 버려서 기능을 구현하기전에 완벽하게 만들려는 경향이 있었는데, 우테코에 들어와서 일단 구현하는것을 우선으로 두도록 변했다." 라고 답변을 해주셨었는데, 이 부분이 나에게 크게 와닿았다.

나 같은 경우도 혼자서 공부를 하다보니, 제가 개발을 하려는 것의 끝이란 어디인가?에 대해서 많이 고민을 하고 혼란스러움을 겪고 있고, 앞으로도 그럴 것이라고 생각한다.

아직 공부해야할 것은 많은데, 그러면 이런 공부를 다 하고 나서야 프로젝트를 만들어볼수 있는 것일까? 라는 생각도 들었었는데, 우테코에 들어와서 이러한 부분이 많이 나아졌다는 말씀에 많은 위안과 동기부여를 얻을 수 있었다.

또한 다른 분은 "나보다 개발적으로 더 잘하는 사람이 이게 좋다고 하면, 그냥 무작정 따라가는 식이었는데, 우테코를 진행하면서 이게 정말 좋은 것인가? 왜 좋은거지?" 같은 생각을 하게 되면서 능동적으로 판단할 수 있는 능력을 기르게 됐다고 말씀해주셨다.

이 부분 또한 엄청나게 공감이 되었다.

우테코에 합격하기 전이지만, 프리코스만으로도 디스코드에서 많은 분들과 소통하고 의견을 나누어보며 홀로 공부할때와는 다른 많은 장점을 느끼고 있다.

홀로 공부할때는 이게 왜 좋은지에 대해서 생각하더라도 정확한 논리를 갖추기보다 말끝을 흐리는 느낌이었다면, 프리코스를 진행하면서는 내 의견에 스스로 근거를 갖기 위해서 적극적으로 더 노력중이다.

뜻이 맞는 동료들과 함께 성장한다는 것의 중요성을 깨닫는 요즘이다.

🔍 8. 유효성 검증은 어디서 이루어져야하는가 ?

디스코드에서 validator는 클래스로 만드는게 좋은가? 아님 utils로직으로 처리하는가? 라는 주제의 글이 올라왔었다.

이에 많은 분들이 유효성 검증 클래스를 따로 만들어야하는가? 아니면 도메인 클래스 내에서 유효성 검증을 직접 해주어야하는가? 에 대한 의견들을 남겨주셨다.

이와 관련해서 나만의 의견을 남겨보면서 스스로 더 나은 유효성 검증에 대해서 한번 더 고민 해볼 수 있는 기회를 가질 수 있었다.

⬇️ 밑에는 제가 직접 작성한 댓글입니다. ⬇️
저는 현재 3주차까지도 해당 모델 클래스 안에서 내부 validate 메서드로 선언해서 유효성 검증을 다 해주었는데요.
저 또한 응집도를 높이고 가독성을 높이는 방법이라고 생각했습니다.
만약에 아이디든 비밀번호든, 닉네임이든.. 모든 속성이 N자 이상의 글자수를 넘어야하고 특수문자는 포함하지 않는다 ! 같은 교집합의 제약이 존재하는 경우에는 validate 클래스 하나로 묶어주는 것이 좋다고 생각하지만,
지금까지는 그정도의 공통된 속성을 갖고 있는 모델들이 존재하진 않았던것 같아요.
이건 모델의 역할을 어디까지 부여할것이느냐? 에 따른 관점의 차이라고 생각이 됩니다.
2주차에 단일 자동차 이름에 대한 Car 클래스를 선언해주었는데, 해당 클래스 안에서 유효성 검사가 존재하지 않는다면 이 클래스의 존재의 의미도 사라지게 되더라구요.
하지만 또 해당 클래스가 존재하지 않는다면 따로 유틸함수나, validator 클래스를 선언해서 유효성 검사를 어차피 해주었어야 했는데, 이러면 또 응집도가 떨어지게 될거라는 판단에 그냥 클래스로 선언해서 관리했습니다.
... 중략
당시 상황에 더 효율적으로 작동하는 방법은 있을지라도, 맞고 틀림은 없다고 생각합니다.

profile
https://brgndy.me/ 로 옮기는 중입니다 :)

0개의 댓글