리팩터링의 필요성
- 코드 수정은 사람이 한다. 사람은 코드의 미적 상태에 민감하다.
- 설계가 나쁜 시스템은 수정하기 어렵다. 원하는 동작을 수행하도록 하기 위해 수정해야할 부분을 찾고,
기존 코드와 잘 맞물려 작동하게 할 방법을 강구하기가 어렵기 때문이다. - 프로그램이 새로운 기능을 추가하기에 편한 구조가 아니라면, 먼저 기능을 추가하기 쉬운 형태로
리팩터링하고 나서 원하는 기능을 추가한다.
= 프로그램의 작동 방식을 더 쉽게 파악할 수 있도록 코드를 여러 함수와 프로그램 요소로 재구성 - 프로그램이 변경될 가능성이 없다면 안 해도 되지만, 기능추가 안 할거야? 그럼 해야 됨.
- 다른 사람이 코드를 읽고 이해해야 할 일이 생겼는데 로직을 파악하는 게 어렵다면 리팩터링이 필요
테스트 코드의 필요성
- 리팩터링에서 테스트의 역할은 굉장히 굉장히 중요하다.
- 리팩터링 기법들이 버그 발생 여지를 최소화하도록 구성되어 있지만, 실제 작업은 사람이 한다.
- 언제든 실수할 수 있다.
- 프로그램이 클수록 수정 과정에서 예상치 못한 문제가 발생할 가능성이 크다.
- 테스트 실행은 간단하게 만든다. 복잡하다면 테스트 방법을 꼭 정리해둔다.
- 리팩터링 전에 제대로 된 테스트부터 마련한다. 테스트는 반드시 자가진단하도록 만든다.
- 테스트를 작성하는 데 시간이 좀 걸리지만, 신경 써서 만들어두면 디버깅 시간이 줄어서 전체 작업 시간은 오히려 단축된다.
리팩터링 팁
- 긴 함수를 리팩터링할 때는 먼저 전체 동작을 각각의 부분으로 나눌 수 있는 지점을 찾는다.
- 코드를 분석해서 얻은 부분 (예시에서는 "한 번의 공연에 대한 요금 계산") 을 다음에 볼 때
분석하지 않고도 뭐하는 부분인지 알 수 있도록 코드에 반영한다.
← 분석한 부분은 내 머릿 속에 저장되고, 내 머릿 속 저장공간은 휘발성이 매우 높다. - 긴 코드 중 분석된 부분을 함수로 추출한다.
- 그 함수에는 그 코드가 하는 일을 설명해주는 함수명을 지어준다.
- 변수의 유효범위가 바뀌어서 새로 만든 함수에서 바로 사용할 수 없고, 값이 바뀌지 않는 변수는 매개변수로 받아서 사용
- 함수 내에서 값이 바뀌는 함수는 함수 안에서 초기화해준다.
- 수정 후에는 곧바로 컴파일 후에 테스트하여 실수한 게 없는지 확인한다.
- 아무리 간단한 수정이라도 리팩터링 후에는 항상 테스트
- 한 가지를 수정할 때마다 테스트하면, 오류가 생기더라도 변경 폭이 작기 때문에 살펴볼 범위도 좁아서 문제를 찾고 해결하기가 훨씬 쉽다.
- 조금씩 변경하고 매번 테스트하는 것이 리팩터링의 핵심이다. (리팩터링은 프로그램 수정을 작은 단계로 나눠 진행한다. 그래야 중간에 실수하더라도 버그를 쉽게 찾을 수 있다.)
- 한 번에 너무 많이 수정하려다 실수하면 디버깅하기 어려워져 결과적으로 작업시간이 늘어난다.
- 수정 후 테스트하여 문제가 없다면, 변경사항을 로컬 버전관리 시스템에 커밋한다. 하나의 리팩터링을 끝낼 때마다 커밋하면, 중간에 문제가 생겨도 이전의 정상 상태로 쉽게 돌아갈 수 있다.
(Git을 쓰면 이게 가능해진다.) - 함수를 추출하고 나면, 추출된 함수 코드를 자세히 들여다보면서 지금보다 명확하게 표현할 수 있는 간단한 방법은 없는지 검토한다.
- 임시 변수를 질의 함수로 바꾸기 : 어떤 값에 따라 달라지는 값을 갖는 변수를 추출
- 변수 인라인 하기 : 추출부 생략 -> 필요한 곳에서 바로 사용
- 위 방법으로 지역 변수 지우는 것의 장점 : 추출 작업이 훨씬 쉬워짐. 유효범위를 신경써야할 대상이 줄어들기 때문
- amoutFor로 뽑아낸 thisAmount는 변하지 않으므로 이것을 사용하는 곳도 변수 인라인 하기 적용
- 이름 짓기는 매우 중요한 작업. 단번에 좋은 이름 짓기 쉽지 않다. 따라서 처음에는 당장 떠오르는 최선의 이름을 사용하다가, 나중에 더 좋은 이름이 떠오를 때 바꾸자
- 반복문 쪼개기 : 반복문을 두 번 도네..?? 성능에 안 좋은 거 아닌가
- 문장 슬라이드 하기 : 관련 값들을 한 곳에 모으기
- 코드가 복잡할수록 단계를 작게 나누자
- 중간 데이터로 옮기는 건 꼭 써봐야겠다.
- 반복문을 파이프라인으로 바꾸기 : 여러줄인 for, while 문을 1줄로 만들기 (java는 stream, 람다식 사용)
- 다형성을 활용해 계산 코드 재구성하기
- 리팩터링은 대부분 코드가 하는 일을 파악하는 데서 시작한다.
- 좋은 코드를 가늠하는 확실한 방법은 '얼마나 수정하기 쉬운가'다.
[마틴 파울러 - 리팩터링] 발췌
'[책 정리] 리팩터링' 카테고리의 다른 글
[월부] 재테크 기초반 2주차 수강 후기 (0) | 2024.11.25 |
---|---|
5장. 리팩터링 카탈로그 보는 법 (0) | 2024.01.06 |
4장. 테스트 구축하기 (0) | 2024.01.01 |
3장. 코드에서 나는 악취 (0) | 2023.12.31 |
2장. 리팩터링 원칙 (0) | 2023.12.31 |