# 3. 10년 이상 쓸 수 있는 지속 가능한 코드 작성 ###### tags: `지호`, `프론트엔드 Back to the Basics` --- ## 1. 좋은 코드란 무엇인가 ### 좋은 코드 - 사람이 읽기 좋아야 한다 - 간결하고 의도가 명확해야한다 - 의존성이 적어야한다 - 하나의 함수, 메소드, 클래스는 각각 명확한 하나의 책임만 지녀야한다 ### 디버깅 1. 정상 시스템의 동작, 그러니까 기대하는 동작을 정의한다 2. 원인을 섣불리 추측하지 않고, 일단은 "모른다"고 생각하고 출발한다 3. 근본적인 원인을 알 때까지 최대한 많은 데이터를 모으며 현상을 관찰한다 4. 증상이 아닌 원인을 수정한다 <br/> ## 2.테스트와 TDD, BDD ### 테스트 - 실행 속도가 빨라야 한다 - 내부 구현을 변경했다고 해서 테스트를 실패하면 안된다 - 입출력 위주의 인터페이스를 중심으로 작성한다 - 버그를 찾을 수 있어야 한다 - 테스트 결과에 일관성이 있어야 한다 - 의도가 명확히 드러나야 한다 ### 코드 커버리지 - 보통 라인 수를 기준으로 측정 - 70%를 넘으면 훌륭 ### TDD와 BDD - 테스트를 먼저 작성하고 그 후 실제 코드를 작성하는 방법 - 장점 - 테스트를 먼저 작성하기 때문에 전체 코드에서 얼마나 많은 코드가 테스트되는가를 측정하는 테스트 커버리지 비율이 자연스럽게 높아진다 - 테스트 되는 것만 코드로 작성하므로 코드가 방대해지지 않는다 - 버그때문에 발생하는 시간 낭비 줄여주고, 코드가 원하는 바를 명확히 달성하는지 쉽게 확인할 수 있다 - 방법 1. 테스트를 먼저 작성한다 (만족하는 코드가 없는 상태이므로 당연히 테스트는 실패) 2. 테스트를 통과하는 코드를 작성한다 3. 리팩토링: 중복이 보이거나 더 개선할 방법이 있다면 코드를 개선 <br/> ## 3. 리팩토링 ### 대상 - 너무 큰 함수나 클래스 - 이름이 명확하지 않은 함수나 변수 이름 - 중복 코드 - 전역 변수 -> 가능하면 함수 내 혹은 모듈 내에 두자 - 과도한 콜수, 조건문 중첩 - 과도하게 긴 식별자 ### 방법 1. 함수 추출 혹은 옯기기: 로직을 별도의 함수나 모듈로 분리 2. 중간 변수 도입: 어떤 값인지 설명하는 중간 변수 3. var는 let, const로 변환 4. 함수의 사이드 이펙트 최소화 -> 순수함수 ( 똑같은 입력이 주어졌을 때 똑같은 출력이 나오는 함수) 5. 빠른 실패 (fast fail) 6. 반복문 보다는 파이프 (filter, forEach...) 7. switch 대신 object literal ```javascript= function sayJob(job) { switch(job) { case 'engineer': console.log('엔지니어'); break; case 'developer': console.log('개발자'); break; case 'designer': console.log('디자이너'); break; } } to function sayJob(job) { const translated = { engineer: '엔지니어', developer: '개발자', designer: '디자이너', }; console.log(translated[job]); } ``` 9. 배열이나 객체는 불변 객체처럼 Immutable하게 다루기 ```javascript= const blackPink = [ '지수', '제니', '로제', '리사' ]; blackPink.forEach((value, index) => { blackPink[index] += '❤️'; }); console.log(blackPink); to const blackPink = [ '지수', '제니', '로제', '리사' ]; const blackPinkWithLove = blackPink.map((value, index) => { blackPink[index] += '❤️'; }); console.log(blackPinkWithLove); ``` 10. 문자열 합치기 보다는 ES6 템플릿 문자열