티스토리 뷰

본 포스팅은 우아한테크코스 7기 프론트엔드 전형 지원에 대한 회고록입니다.

 

 이번 주 과제는 자동차 경주 게임 제작입니다. 사용자의 입력을 받아 게임을 진행하고, 최종 우승자를 선정하는 프로그램을 만들었습니다.

 

 기능 요구 사항은 총 5가지였고, 이전 기수에서 동일한 주제를 다뤄 익숙한 느낌이 들었습니다. 그러나 2주차부터는 프로그래밍 요구사항이 추가되었고, 매주 요구사항이 하나씩 더해지는 패턴을 확인할 수 있었습니다.

 

 이번 과제의 주요 요구사항은 indent depth 제한, 삼항 연산자 금지, 함수 단일 책임 원칙 준수, 그리고 Jest를 이용한 테스트 코드 작성이 있었습니다. 대부분의 요구사항은 이해가 됐지만, 삼항 연산자를 금지하는 이유는 다소 의문이 들었습니다. 평소 삼항 연산자가 코드 가독성을 높인다고 생각하며 자주 사용했기에, 과제를 마친 . 후왜 사용이 제한되었는지 나름대로 조사해 보았습니다.

 

삼항연산자, 왜 사용을 제한했을까? 🤔

 

 처음엔 "삼항 연산자가 최적화에 불리하여 사용을 제한하는 걸까?"라는 가설을 세웠습니다.

 

 그러나 결론적으로 if/else문과 삼항연산자의 실행 속도 차이는 거의 무시할 수 있는 수준이라는 사실을 알게 되었습니다. if/else문 컴파일러에서 삼항 연산자보다 몇 개의 추가 명령어를 생성하지만, 이는 전체 성능에 큰 영향을 주지 않습니다.

 

 여기서 흥미로운 점은 if/else문이 삼항 연산자보다 약간 큰 코드 크기를 가지지만, 실제 실행 시에는 더 적은 명령어를 실행한다는 것입니다. 이는 컴파일러가 if/else문을 조건에 따라 필요한 명령어 경로만 실행하도록 최적화하기 때문입니다. 반면 삼항 연산자는 짧고 간결하지만 모든 조건을 미리 준비하려는 경향이 있어, 필요하지 않은 명령어도 생성될 수 있습니다. 따라서 두 방식 간의 실행 속도 차이는 거의 없다고 볼 수 있습니다.

 

Colin.js

Colin.js

colinchjs.github.io

 

Ternary Operator versus the if/else statement … | Beningo Embedded Group

© 2024 Beningo Embedded Group. All Rights Reserved.

www.beningo.com

 

뻘글) 삼항연산자 vs if문, 누가 최적화를 더 잘해줄까?

대학때 삼항연산자를 배우면서 많은 교수님들이 삼항연산자를 쓰지 말라고 하셨다. 그 이유는 코드의 빠르고 느리고를 떠나서 가독성이 좋지 않으니 쓰지 말라고 하셨다. 그리고 그 당시의 나

velog.io

 

그렇다면, 가독성이 문제?

 

 조사한 결과 삼항 연산자의 사용 제한은 가독성 때문임을 알게 되었습니다. 삼항 연산자는 단순한 조건에서는 코드가 간결해지지만, 복잡한 조건을 처리할 때는 오히려 가독성을 해칠 수 있습니다. 

 

 저도 평소 간단한 조건에서는 삼항 연산자를 사용하고, 복잡한 논리에는 if/else문을 사용하는 방식으로 코드를 작성하고 있었습니다.

// OK
int a = (b > 10) ? c : d;  

// 가독성 저하
int a = b > 10 ? c < 20 ? 50 : 80 : e == 2 ? 4 : 8;

 

 조사를 하면서 검색해보니, 삼항 연산자의 가독성 이슈는 뜨거운 주제였습니다. 가독성을 흐트릴정도로 중첩하거나 과도하게 쓰는 경우가 많았던 것 같습니다. 삼항 연산자가 논란의 중심이었다니, 처음 알게 됐네요🤦‍♀️

 


 

코드 리뷰를 통해 얻은 피드백

 

  이번 과제에서 가장 크게 성장한 부분은 코드 리뷰였습니다. 1주차 과제가 마감되어 다른 참가자와 함께 코드 리뷰를 진행했습니다.

 

 특히 기억에 남는 피드백은 macth 함수 피드백과 예외 처리 관련 피드백이었습니다. 1주차 과제에서 커스텀 구분자를 추출하기 위해 다음과 같은 코드를 작성했는데요.

export function getCustomSeparator(userInput) {
  const customSeparator = userInput.match(/^\/\/(\D)\\n/);

  return Array.isArray(customSeparator) && customSeparator.length
 }

 

 

 이 코드에서는 match 메서드가 정규식과 매치되지 않으면 null을 반환한다는 점에서, 배열 체크가 필요 없다는 피드백을 받았습니다. 덕분에 2주차 과제에서는 이 부분을 참고해 리팩토링할 수 있었습니다.

 

 

String.prototype.match() - JavaScript | MDN

match() 메서드는 문자열이 정규식과 매치되는 부분을 검색합니다.

developer.mozilla.org

return customSeparator && customSeparator[1];

 

 불일치할 때 무조건 null을 return하기 때문에, 아예 이런 식의 리팩토링도 가능할 것 같습니다.

export function getCustomSeparator(userInput) {
  return userInput.match(/^\/\/(\D)\\n/)?.[1];
}

 

 또 다른 피드백은 예외 메시지를 객체로 관리하라는 것이었습니다. 기존에는 에러 발생 시 사용자가 무엇을 잘못했는지 알기 어려웠습니다. 이번 과제에서는 상수 파일에 에러 메시지를 객체로 관리하여 사용자 친화적인 예외 처리를 구현했습니다.

 

 상수만 모아놓은 별도의 constants 파일에 객체로 에러 메시지를 뽑아냈습니다.

export const ERROR_MESSAGES = {
  INVALID_PLAYER_NAME:
    '[ERROR] 이름은 1자에서 5자 이하여야 하며 영문,숫자,한글,특수문자 -_!: 만 사용할 수 있습니다.',
  INVALID_MOVE_COUNT: '[ERROR] 이동 횟수는 1 이상의 정수로 입력해야 합니다.',
};

 

 


 

테스트 코드와 모킹 함수 학습

 

 또 다른 성장은 테스트 코드 작성과 모킹 함수 학습이었습니다. 기능 구현은 금방 완성했지만, 사용자 입력을 모킹해 테스트하는 방법을 익히는 과정이 어려웠습니다.

 

Mock Functions · Jest

Mock functions allow you to test the links between code by erasing the actual implementation of a function, capturing calls to the function (and the parameters passed in those calls), capturing instances of constructor functions when instantiated with new,

jestjs.io

 생각보다 직관적인 개념인데, mock에 대한 개념이 잘 잡히지 않아 애를 먹었습니다. 결과적으로, 프리코스에서 제공된 모킹 함수를 사용하여 기능별 단위 테스트를 만들었습니다. 모킹함수를 직접 제작하지 않았지만, 그래도 모킹에 대한 이해가 잡혀 무척 뿌듯했습니다.

 

다음 과제 계획

 

 다음 주 과제에서는 모듈 설계에 집중할 계획입니다. 이번 과제에서는 기능별로 테스트 코드를 분리하고, 각 기능이 독립적으로 테스트될 수 있도록 구조화하면서, 모듈화와 테스트의 중요성을 체감하게 되었습니다.  

 

 이를 통해 단순히 기능별 분리가 아니라, 코드의 재사용성과 유지보수성을 높일 수 있는 방향으로 개선해 나가고자 합니다.

 

 완전한 TDD 방식보다는 모듈화 구조에 따른 테스트 작성에 중점을 두어, 코드 간 결합도를 낮추고 각 기능의 안정성을 강화하는 전략을 적용할 계획입니다.

 

GitHub - mindaaaa/javascript-racingcar-7

Contribute to mindaaaa/javascript-racingcar-7 development by creating an account on GitHub.

github.com

 

댓글