Search
⚒️

계산기 미션 공통 피드백

1. 주석에 담아야하는 대상

우리가 주석을 작성한다면 어떤걸 작성하면 좋을까요? 주석은 실제 코드를 포함하여 해당 부분을 이해하는데 더 많은 시간을 할애해야하고, 화면의 일정한 부분을 차지합니다. 그래서 주석 또한 코드의 일부이므로 작성할 때는 분명한 이유가 있어야 합니다. 그럼 작성해도 괜찮은 주석과, 그렇지 않은 주석 사이의 경계를 어떻게 정할 수 있을까요?

1) 감독의 설명을 포함하기

영화에는 감독이 자신의 통찰을 설명하고, 영화가 만들어진 과정을 관람객이 잘 이해하게 도와주는 '감독의 설명'을 담은 감독판 트랙이 있습니다다. 이와 비슷한 방식으로 중요한 통찰을 기록한 주석을 코드에 포함시킨다면, 읽는 사람으로 하여금 해당 코드에 대한 더 높은 이해를 할 수 있게 도와줍니다.
예를 들면
// 이 데이터에서 이진트리는 해시테이블보다 40%정도 빠르다. // 재귀함수를 이용하면, 기존의 100line이 될수 있는 코드가 단 20줄로 정리된다. 반면 성능은 유의미한 차이가 없다.
JavaScript
이러한 주석은 코드를 읽는 사람에게 코드를 최적화하느라 시간을 허비하지 않게 도와줍니다.

2) 코드에 있는 결함을 설명하기

코드는 지속적으로 진화하며, 그러는 과정 중에 버그를 갖습니다. 이러한 결함을 설명하는 것을 부끄러워할 필요는 없습니다. 숨기는게 문제이지, 결함을 공개적으로 드러내고 수정할 여지를 남겨야 합니다. 예를 들어 개선이 필요할 때 아래와 같이 작성할 수 있습니다.
// TODO: JPEG외 다른 이미지 포맷도 처리할 수 있어야 한다
JavaScript
// AsyncMode should be deprecated export function isAsyncMode(object: any) { if (__DEV__) { if (!hasWarnedAboutDeprecatedIsAsyncMode) { hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint console['warn']( 'The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 18+.', ); } } return false; }
JavaScript
이러한 결함 설명과, 추가로 해야하는 일의 경우 팀내에서 컨벤션을 맞추면 좋습니다.

3) 상수에 대한 설명

상수를 정의할 때는 종종 그 상수가 무엇을 하는지, 그것이 왜 특정한 값을 갖게 되는지 사연이 있는 경우가 있습니다. 예를 들면 아래와 같이 작성된 경우, 주석을 통해 해당 코드에 대한 이해도를 더 높게 가져갈 수 있습니다.
// 합리적인 한계 - 1000개 이상을 구독하는 사람은 기획 논의상 없다. const MAX_SUBSCRIPTIONS = 1000 // 사용자들은 0.72가 크기/해당도 대비 최선이라고 생각한다. const IMAGE_QUALITY = 0.72
JavaScript

4) 사람들이 쉽게 빠질 것 같은 함정을 미리 경고하기

예를 들어 사용자에게 이메일을 보내는 써드파티 라이브러리와 함수를 작성했다고 해봅시다. 이 때 아래와 같은 이슈가 있고, 그에 대해 작성해준다면, 함께 개발하는 사람은 1분정도 소요된다는걸 사용자에게 애니메이션이나, 메시지로 알림을 줄 수 있습니다. 그렇지 않다면, 왜 시간이 1분이나 걸리는지 그것이 에러가 아닌지 확인하는 작업을 해야할수도 있습니다.
// 이 함수는 외부 서비스를 호출하여, 이메일을 발송한다 (1분정도 소요) function sendEmail() { ... }
JavaScript

2. 불필요한 임시 변수는 줄여보자

불필요한 임시 변수들

불필요한 중간 변수들을 줄이면 코드는 더욱 명확하해집니다.
const year = new Date().getFullYear() message.lastVistedYear = year
JavaScript
여기서 year변수는 굳이 필요하지 않다.
첫째로, 명확성에 도움이 되지 않는다. new Date().getFullYear()로 이미 명확하다.
한 번만 사용되어 중복되는 코드를 재사용하지 않는다.

3. 변수는 좁은 곳에, 광역기는 아껴쓰자

"전역 변수를 피하라" 라는 말을 누구나 한번쯤 들어봤습니다.
전역 변수는 언제 어디서 어떻게 사용되는지 확인하기 어렵고, 지역 변수와 이름이 중복되는 문제를 일으킬 수 있기 때문에 모든 변수의 범위를 좁히는 일은 거의 필수입니다. 그래서 많은 프로그래밍 언어들이 모듈, 클래스, 함수, 블록 범위 같이 다양한 범위/접근 수준을 제공합니다. 더 제한적인 접근을 이용하면 변수가 더 적은 줄 내에서만 보이기 때문에 일반적으로 더 좋습니다. 왜냐하면 코드를 읽는 사람이 한꺼번에 생각해야하는 변수 수를 줄여주기 때문입니다. 모든 변수의 범위를 1/2로 축소시키면 한 번에 읽어야 하는 변수의 수는 절반 이상으로 줄어듭니다.

값을 한 번만 할당하는 변수 선호하기 (let 대신 const)

변수들의 값이 변한다면 프로그램을 따라가는 일은 점점 어려워집니다. 변수 값을 일일히 기억하려면 추가적인 어려움이 야기되기 때문입니다. 이러한 문제를 해결하기 위해서는 값을 한 번만 할당하는 변수를 선호하는 것입니다. 그래서 변수에 값을 한 번만 할당하게 할 수 없더라도, 최대한 적은 횟수로 변하게 하는 일은 대체로 도움이 됩니다.
변수값이 달라지는 곳이 많을수록 현재값을 추측하기 더 어려워집니다!
// 2개의 계산기가 필요하다면 아래 코드는 어떤 어려움이 있을까요?

4. 프로그래밍에서 이름은 작은 설명문이다

변수의 이름은 작은 설명문입니다. 적절한 네이밍은, 코드의 재사용성을 높이고, 다른 사람이 나의 코드를 읽고 함께 작업할 때 실수할 확률 또한 줄어듭니다.

숫자는 이름이 아니다

5. 재사용은 의미를 더 명확하게 만들어 준다.

6. 기타

1) className에 대한 비교

if (event.target.className !== 'modifier') return;
JavaScript

2) 이상적인 파라미터 갯수

//before function amountInvoiced(startDate, endDate) {} function amountRecevived(startDate, endDate) {} function amountOverdue(startDate, endDate) {} //after function amountInvoiced(dateRange) {} function amountRecevived(dateRange) {} function amountOverdue(dateRange) {}
JavaScript
매개변수가 많아지면 함수가 호출할 때 전달해야할 인수의 순서를 고려해야합니다. 이는 함수의 사용 방법을 어렵게 만들고 실수를 발생시킬 가능성 또한 높아지게 만드는데요. 또한 매개변수의 개수나 순서가 변경되면 함수의 호출 방법도 변경되므로 함수를 사용하는 코드 전체가 영향을 받습니다. 함수의 매개변수는 코드 이해에 방해가 되는 요소이므로 이상적인 매개변수 개수는 0개이며, 적을 수록 좋습니다. 이상적인 함수는 한가지 일만 해야 하며 가급적 작게 만들어야합니다. 그래서 가능하면 매개변수가 많이 필요해진다면 객체를 인수로 전달받는 것이 의미를 명확하게 하는데 있어 더 도움이 됩니다.
it ("두 수를 더한다", () => { const inputValues = ["1", "+", "3", "="] operatorNumber(inputValues, 4) })
JavaScript

3) if문 inline

4) Task check (구현한 요구사항 체크)

가능하면, PR을 보낼 때는 README 또는 PR에 본인이 구현한 요구사항들을 체크해주시면, 현재 진행한 상황과 피드백 줄 내용들이 명확해집니다.
### 🎯 구현 사항 ✅ 2개의 숫자에 대해 덧셈이 가능하다. ✅ 2개의 숫자에 대해 뺄셈이 가능하다. ✅ 2개의 숫자에 대해 곱셈이 가능하다. ✅ 2개의 숫자에 대해 나눗셈이 가능하다. ✅ AC(All Clear)버튼을 누르면 0으로 초기화 한다. ✅ 숫자는 한번에 최대 3자리 수까지 입력 가능하다. ✅ 계산 결과를 표현할 때 소수점 이하는 버림한다.
Plain Text

5) 원격저장소에 push해야할 것과 말아야할 것

5) 테스트 파일에 .spec이 붙은 이유

테스트파일에
.spec
Plain Text
을 붙이는 이유는 이 제품의 사양(Specification)이 어떻게 되는지 알려주는 테스트 파일이기 때문입니다. 제품의 사양을 작성하는 곳에, 제품의 구현 부분이 작성되어있다면 어색해지겠죠?

6) 예외사항에 대한 고려, 엣지 케이스

개발자는 늘 예외사항에 대한 고려를 해야하는데요. switch case 구문 뿐만 아니라, 예외 사항은 없을지 고민해본다면 더 안정적인 코드가 될 수 있습니다.

7. 랜덤값에 대한 테스트 고민, 우리는 무엇을 테스트하는게 맞을까?

테스트하기 고민이 들때 우리가 생각해봐야할 것은 테스트 가능한 코드와 테스트하기 힘든 부분을 분리하는 것입니다.
const FORWARD_NUM = 4 const getRandomNumber = () => { return Math.floor(Math.random() * 10) } function Car() { this.poistion = 0 this.move = () => { if (getRandomNumber() >= FORWARD_NUM) { this.position++ } } }
JavaScript
위와 같은 코드에서 테스트는 매번 move에서 진행되는 숫자 값이 달라질 수 밖에 없는데요. 이를 테스트 가능한 코드로 리팩토링 한다면 아래와 같이 분리할 수 있습니다.
function Car() { this.poistion = 0 this.move = (number) => { if (number >= FORWARD_NUM) { this.position++ } } }
JavaScript
테스트하기 어려운 부분이나, 헷갈리는 부분이 있다면 테스트 가능하게끔 리팩터링해보세요.