리팩토링이란?
품질을 향상시키고 코드의 동작을 변화하지 않고 안전하게 코드를 변경하는 절차를 말한다. 리팩토링을 하기 위해서는 변수명, 함수명, 클래스 명 등 네이밍 규칙을 따르고 일관성 있게 만들고 확장성까지 고려해 야 한다.
리팩토링을 하기위해 사용할 수 있는 여러가지 지침은 아래와 같다.
- SOLID : 객체지향 5원칙
- DRY (Don’t Repeat Yourself) : 같은 일을 두 번 하지 말라.
- KISS (Keep It Simple, Stupid) : 단순하게 하라.
- GRASP (General Responsibility Assignment Software Patterns) : 책임을 부여하는 원칙들을 말하고 있는 패턴
- YAGNI (You Ain’t Gonna Need It) : 정말 필요할 때까지 해당 기능을 만들지 말라.
실행 테스트나 수동 절차, 어떻게 동작하는지 최소한의 설명이 없는 코드는 리팩토링 할 수 없으며, 테스트를 거치지 않 고 코드를 변경하는 것은 동작을 보장할 수 없으므로 리팩토링이 아니라 단지 코드를 변경하는 것이라고 볼 수 있다.
자바스크립트 자체에 대한 배경지식
- ECMAScript : ECMA International에 의해 제정된
ECMA-262
기술 규격에 의해 정의된 범용 스크립트 언어 - TC39 :
ECMAScript
사양에서 새로운 기능을 살펴보고 채택하는 책임을 맡은 위원회 - JavaScript :
ECMA-262
를 만족하는 스크립트 언어의 한 종류 JavaScript Engine : JavaScript 코드를 이해하고 실행하는 프로그램 또는 인터프리터로 대표적인 엔진은 Google에서 제작한 V8이 있다. (Nodejs가 V8과 비동기 이벤트 처리 라이브러리인
libuv
를 결합하여 사용하고 있다)- BABEL : 입력과 출력이 모두 자바스크립트인 컴파일러로, 초기의 바벨은 ES6 코드를 ES5 코드로 변환해주는 일만 했지만, 현재는 React의 JSX 문법, TypeScript, 코드 압축, Proposal까지 처리하는 역할을 한다.
애자일 소프트웨어 개발 방법론
테스트 주도 개발(TDD, Test-Driven Development)
짧은 개발 사이클을 반복하는 SW 개발 프로세스 중 하나이다. 요구사항을 검증하는 자동화된 테스트 케이스를 먼저 작성하고 이를 통과하는 코드를 추가하는 단계로 반복하여 리팩토링을 진행한다.
기존에는 Product 코드를 먼저 짜고 TEST 코드를 작성했다면, TDD는 이와 반대를 지향한다. TEST 케이스와 자동화 TEST 코드를 먼저 작성하고, Product 코드를 작성하는 것이다.
행동 주도 개발(BDD, Behavior-Driven Development)
TDD에서 파생된 개념으로 시나리오를 기반으로 테스트 케이스를 작성하며 함수 단위 테스트를 권장하지 않는다. 이 시나리오는 개발자가 아닌 사람이 봐도 이해할 수 있을 정도로의 레벨을 권장하며, 하나의 시나리오는 Given, When, Then 구조를 가지는 것을 기본 패턴으로 권장한다.
- Feature : 테스트에 대상의 기능/책임을 명시한다.
- Scenario : 테스트 목적에 대한 상황을 설명한다.
- Given : 시나리오 진행에 필요한 값을 설정한다.
- When : 시나리오를 진행하는데 필요한 조건을 명시한다.
- Then : 시나리오를 완료했을 때 보장해야 하는 결과를 명시한다.
Ex) 테스트 대상은 A 상태에서 출발하며(Given) 어떤 상태 변화를 가했을 때(When) 기대하는 상태로 완료되어야 한다.(Then)
TDD와 BDD의 차이
TDD는 테스트 자체에 집중해 개발하는 반면 BDD는 비즈니스 요구사항에 집중하여 테스트 케이스를 개발한다.
간단한 구조 리팩토링
이름 바꾸기
- 변수 이름에 한 문자(i, j, k 등)을 사용하는 것은 찾기, 변경 시에 문제가 발생할 수도 있고, 겹쳐 쓸 위험도 있으며, 변수 이름에 무엇이 들어있는 지에 대한 정보를 주지 않기때문에 의미가 있는 변수명을 사용해야 한다.
- 스네이크 표기법(Ex.
somewhere_over_the_rainbow
) 대신 카멜 표기법을(Ex.someWhereOverTheRainbow
)를 사용하라
불필요한 코드 제거 (YAGNI)
- 죽은코드, 즉 사용하지 않는 코드는 제거한다.
- 추측성 코드나 주석 처리된 코드는 YAGNI 원칙에 위배되므로 제거하는게 좋다. (추측성 코드는 무언가를 하기때문에 죽은 코드가 아니다.)
- 무의미한 공백은 사용하는 IDE에 따라 오류가 발생할 수도 있고 버전 관리 노이즈 또는 충돌이 발생할 수도 있으므로 제거한다.
- 불필요한 코드를 제거한다.
변수
- 긴 코드 줄 같은 경우는 축약 기능(복합 대입 연산자, +=, /=, -= 등)를 사용한다.
메서드 체이닝(Method Chaining)
을 통해 단순화 시킨다.호이스팅(Hoisting)
에 유의하며 리팩토링을 진행한다.
문자열
- 문자열 연결은 + 연산자 또는 백틱(`)을 사용한 템플릿 문자열(리터럴)을 사용한다.
- 문자열에서 특정 문자를 추출하기 위해서 반복문과 Split 대신 정규 표현식을 사용하라.
- 긴 문자열을 처리할 때는 상황에 따라 다르지만 줄바꿈 문자가 있도록 하려면 템플릿 문자열(리터럴)을 사용한다.
배열을 이용한 작업: 반복문, forEach, map
- for …in: 객체의 모든 열거 가능한 속성에 대해서 반복
- for …of: [Symbol.iterator] 속성을 가지는 컬렉션 전용
- forEach: 내부의 익명함수를 아주 쉽게 추출할 수 있다. (추출하고 싶지 않다면 화살표 함수를 사용)
- Map: 반복문을 돌면서 배열 안의 요소를 1:1로 매칭시켜 줌