리팩토링
: 프로그램의 가치를 높이는 코딩 정리 기술
Fowler의 정의
: 관측 가능한 동작의 수정 없이 소프트웨어의 내부 구조를 변경하여 더욱 이해하기 쉽고 변경하기 쉬운 구조로 만드는 일
: 관측 가능한 동작의 수정 없이 리팩토링을 적용하여 소프트웨어를 재구조화함
목적
- 소프트웨어를 이해하기 쉽고 변경하기 쉽도록 만들기 위해
- 기능 추가 없이 코드를 깨끗하게, 이해가 쉽게 해 변경이 쉽도록, 때로 크기도 준다
성능 최적화와는 성질이 다름
원리
리팩토링의 이유
- 설계 향상
- 쉬운 이해
- 버그 발견
- 빠른 프로그램
리팩토링 시기
- 기능을 추가할 때
- 버그를 수정할 필요가 있을 때
- 코드 리뷰할 때
리팩토링과 함께하는 문제
- DB : 비즈니스 애플리케이션은 DB와 강하게 결합되어있다. 코드는 변경하기 쉬우나 DB는 그렇지 않다
- 인터페이스 변경 : 호출하는 코드를 모두 가지고 있다면 문제 없지만, 없다면 인터페이스는 "published"된 것으로 바꿀 수 없다.
BAD SMELL
- 중복된 코드
- 긴 메서드
- 큰 클래스 -> 응집력이 낮음
- 긴 매개변수 리스트
- 발산하는 변경 = 나비효과 = 연관이 많아 변경을 하면 연관된 클래스/메서드를 모두 변경해야하는 일 -> 응집과 연관
- 기능 산재(shotgun Surgery) -> 변경 위해 여러 다른 클래스에 있는 작은 수정이 많음
- 잘못된 소속(Feature Envy) -> 메서드가 다른 클래스로부터 너무 많은 정보를 요청
- 데이터 뭉치(Data Clumps) -> 클래스 안에 데이터가 너무 많고 함수는 별로 없는 경우, 데이터를 연관된 것끼리 자르거나 데이터를 이용하는 오퍼레이션과 가깝게 이동하게 함
- 강박적 기본 타입 사용(Primitive Obsession) -> 꼭 필요한 것만 만들기.
- Switch 문장 -> 객체지향의 폴리몰피즘 이용하여 줄이기
- 평행 상속 계층(Parallel Inheritance Hierachies) -> 평행 상속계층(스트레티지/브리지 같은 구조)이 너무 남발되지 않게 하기
- 직무 유기 클래스(Lazy Class) -> 메소드나 데이터 하나 달랑있는 클래스
- 막연한 범용 코드(Speculative Generality)
- 임시 필드(Temporary Field) -> 객체의 속성이 어떤 환경에만 할당 및 사용됨
- 메시지 체인
- 과잉 중개 메소드(Middle Man)
- 지나친 관여(Inappropriate Intimacy)
- 데이터 클래스(Information holder)
- 방치된 상속물(Refused Bequest)
- 불필요한 주석
리팩토링
- 메서드 추출(Extract Method)
그룹으로 묶어도 될 코드 블록을 메서드로 바꾸고 이름이 그 블록의 목적이 되도록 한다
- 임시변수를 메서드 호출로 전환
산술식의 결과를 저장하는 임시 변수를 함수 호출로 사용
- 메서드 이동
메서드가 정의된 클래스보다 다른 클래스의 기능(속성, 오퍼레이션)을 더 많이 사용하면, 많이 사용하는 클래스로 이동
- 조건문을 재정의로 전환
객체의 타입에 따라 다른 동작을 선택하는 조건문을 가질 때, 각 조건을 서브클래스의 메서드로 전환하고, 원래 메소드는 추상화한다
- Null 검사 객체에 위임
Null 객체를 따로 정의하여 조건절을 완전 삭제한다
- 상태 변환 메서드와 값 반환 메서드를 분리
질의는 side effect를 갖지 말아야 한다
- 매개변수 집합을 객체로 전환
같이 있는 것이 자연스러운 파라미터는 객체에 묶고 객체로 전달한다
메서드가 집합을 리턴하는 경우, 집합을 읽기 전용 버전으로 리턴하고 add/remove 메서드를 제공한다
쓸데 없는 파라미터를 너무 많이 넘기면 결합력이 강해져서 좋지 않다
- 여러 개의 조건문을 감시절로 전환
정상 동작에서 if를 남발하지 말고 simple한 예외처리를 해라
정상동작은 그냥 지나가게 하고, 예외 동작에서 if문에 걸리도록. -> 이를 "가드 조건"이라고 함
결론
리팩토링은 SW의 기능을 바꾸지 않고, 더 좋은 코드 구조와, 반복이 적은 코드를 만든다.
대부분의 리팩토링은 중복된 코드를 발견함으로 시작된다
Bad Smell은 시스템이 성숙된 상태임을 발견하는 좋은 비유이다.