리팩토링을 언제 시작하고 언제 그만할지를 판단하는 일은
리팩터링의 작동 원리를 아는 것 못지않게 중요하다.
악취 | 탈취용 리팩터링 기법 |
---|---|
가변 데이터 | 변수 캡슐화하기, 변수 쪼개기, 문장 슬라이드하기, 함수 추출하기, 질의 함수와 변경 함수 분리하기, 세터 제거하기, 파생 변수를 질의 함수로 바꾸기, 여러 함수를 클래스로 묶기, 여러 함수를 변환 함수로 묶기, 참조를 값으로 바꾸기 |
거대한 클래스 | 클래스 추출하기, 슈퍼클래스 추출하기, 타입 코드를 서브클래스로 바꾸기 |
기능 편애 | 함수 옮기기, 함수 추출하기 |
기본형 집착 | 기본형을 객체로 바꾸기, 타입 코드를 서브클래스로 바꾸기, 조건부 로직을 다형성으로 바꾸기, 클래스 추출하기, 매개변수 객체 만들기 |
기이한 이름 | 함수 선언 바꾸기, 변수 이름 바꾸기, 필드 이름 바꾸기 |
긴 매개변수 목록 | 매개변수를 질의 함수로 바꾸기, 객체 통째로 넘기기, 매개변수 객체 만들기, 플래그 인수 제거하기, 여러 함수를 클래스로 묶기 |
긴 함수 | 함수 추출하기, 임시 변수를 질의 함수로 바꾸기, 매개변수 객체 만들기, 객체 통째로 넘기기, 함수를 명령으로 바꾸기, 조건문 분해하기, 조건부 로직을 다형성으로 바꾸기, 반복문 조깨기 |
내부자 거래 | 함수 옮기기, 필드 옮기기, 위임 숨기기, 서브클래스를 위임으로 바꾸기, 슈퍼클래스를 위임으로 바꾸기 |
데이터 뭉치 | 클래스 추출하기, 매개변수 객체 만들기, 객체 통째로 넘기기 |
데이터 클래스 | 레코드 캡슐화하기, 세터 제거하기, 함수 옮기기, 함수 추출하기, 단계 쪼개기 |
뒤엉킨 변경 | 단계 쪼개기, 함수 옮기기, 함수 추출하기, 클래스 추출하기 |
메시지 체인 | 위임 숨기기, 함수 추출하기, 함수 옮기기 |
반복되는 switch문 | 조건부 로직을 다형성으로 바꾸기 |
반복문 | 반복문을 파이프라인으로 바꾸기 |
산탄총 수술 | 함수 옮기기, 필드 옮기기, 여러 함수를 클래스로 묶기, 여러 함수를 변환 함수로 묶기, 단계 쪼개기, 함수 인라인하기, 클래스 인라인하기 |
상속 포기 | 메서드 내리기, 필드 내리기, 서브 클래스를 위임으로 바꾸기, 슈퍼클래스를 위임으로 바꾸기 |
서로 다른 인터페이스의 대안 클래스들 | 함수 선언 바꾸기, 함수 옮기기, 슈퍼클래스 추출하기 |
성의 없는 요소 | 함수 인라인하기, 클래스 인라인하기, 계층 합치기 |
임시 필드 | 클래스 추출하기, 함수 옮기기, 특이 케이스 추가하기 |
전역 데이터 | 변수 캡슐화하기 |
주석 | 함수 추출하기, 함수 선언 바꾸기, Assertion 추가하기 |
중개자 | 중개자 제거하기, 함수 인라인하기, 서브클래스 위임으로 바꾸기, 슈퍼클래스 위임으로 바꾸기 |
중복 코드 | 함수 추출하기, 문장 슬라이드하기, 메서드 올리기 |
추측성 일반화 | 계층 합치기, 함수 인라인하기, 클래스 인라인하기, 함수 선언 바꾸기, 죽은 코드 제거하기 |
함수 이름은 동작 방식이 아닌 의도가 드러나게 짓는다.
무엇을 하는지 코드가 잘 설명해주지 못할수록 함수로 만드는게 유리하다.
클래스 변수와 싱글톤에서 문제가 많이 발생한다.
코드를 수정할 때는 시스템에서 고쳐야 할 딱 한 군데를 찾아서 그 부분만을 수정하면 되는 게 가장 좋다.
뒤엉킨 변경은 SRP(Single Responsibility Principle)
를 위배할 경우 많이 발생한다.
산탄총 수술은 뒤엉킨 변경과 비슷하면서도 정반대다.
코드를 변경할 때마다 자잘하게 수정해야하는 클래스가 많을 때 풍기는 냄새이다.
뒤엉킨 변경 | 산탄총 수술 | |
---|---|---|
원인 | 맥락을 잘 구분하지 못함 | |
해법 원리 | 맥락을 명확히 구분 | |
발생 과정 | 한 코드에 섞여 들어감 | 여러 코드에 흩뿌려짐 |
실제 해결 방법 | 맥락별로 분리 | 맥락별로 모음 |
기능 편애는 흔히 어떤 함수가 자기가 속한 모듈의 함수나 데이터보다 다른 모듈의 함수나 데이터와 상호작용할 일이 더 많을때 풍기는 냄새이다.
중복된 switch문이 문제가 되는 이유는 조건절을 하나 추가할 때 마다 다른 swtich문들도 모두 찾아서 함께 수정해야하기 때문이다.
“나중에 필요할거야”라는 생각으로 당장은 필요 없는 모든 종류의 후킹 포인트와 특이 케이스 처리 로직을 작성해둔 코드에서 풍기는 냄새이다.
간혹 특정 상황에서만 값이 설정되는 필드를 가진 클래스도 있다.
모듈 사이의 데이터 거래가 많으면 결합도(Coupling)가 높아진다고 투덜댄다.
일이 돌아가게 하려면 거래가 이뤄질 수 밖에 없지만, 그 양을 최소로 줄이고 모두 투명하게 처리해야 한다.
한 클래스가 너무 많은 일을 하려다 보면 필드 수가 상당히 늘어난다.
그리고 클래스에 필드가 너무 많으면 중복 코드가 생기기 쉽다.
데이터 클래스란 데이터 필드와 Getter/Setter 메서드로만 구성된 클래스를 말한다.
주석을 남겨야겟다는 생각이 들면, 가장 먼저 주석이 필요 없는 코드로 리팩터링하라!