Chapter03. 코드에서 나는 악취

김신영·2023년 7월 8일
0

Refactoring

목록 보기
3/12
post-thumbnail

서론

리팩토링을 언제 시작하고 언제 그만할지를 판단하는 일은
리팩터링의 작동 원리를 아는 것 못지않게 중요하다.

악취 제거 기법

악취탈취용 리팩터링 기법
가변 데이터변수 캡슐화하기, 변수 쪼개기, 문장 슬라이드하기, 함수 추출하기, 질의 함수와 변경 함수 분리하기, 세터 제거하기, 파생 변수를 질의 함수로 바꾸기, 여러 함수를 클래스로 묶기, 여러 함수를 변환 함수로 묶기, 참조를 값으로 바꾸기
거대한 클래스클래스 추출하기, 슈퍼클래스 추출하기, 타입 코드를 서브클래스로 바꾸기
기능 편애함수 옮기기, 함수 추출하기
기본형 집착기본형을 객체로 바꾸기, 타입 코드를 서브클래스로 바꾸기, 조건부 로직을 다형성으로 바꾸기, 클래스 추출하기, 매개변수 객체 만들기
기이한 이름함수 선언 바꾸기, 변수 이름 바꾸기, 필드 이름 바꾸기
긴 매개변수 목록매개변수를 질의 함수로 바꾸기, 객체 통째로 넘기기, 매개변수 객체 만들기, 플래그 인수 제거하기, 여러 함수를 클래스로 묶기
긴 함수함수 추출하기, 임시 변수를 질의 함수로 바꾸기, 매개변수 객체 만들기, 객체 통째로 넘기기, 함수를 명령으로 바꾸기, 조건문 분해하기, 조건부 로직을 다형성으로 바꾸기, 반복문 조깨기
내부자 거래함수 옮기기, 필드 옮기기, 위임 숨기기, 서브클래스를 위임으로 바꾸기, 슈퍼클래스를 위임으로 바꾸기
데이터 뭉치클래스 추출하기, 매개변수 객체 만들기, 객체 통째로 넘기기
데이터 클래스레코드 캡슐화하기, 세터 제거하기, 함수 옮기기, 함수 추출하기, 단계 쪼개기
뒤엉킨 변경단계 쪼개기, 함수 옮기기, 함수 추출하기, 클래스 추출하기
메시지 체인위임 숨기기, 함수 추출하기, 함수 옮기기
반복되는 switch문조건부 로직을 다형성으로 바꾸기
반복문반복문을 파이프라인으로 바꾸기
산탄총 수술함수 옮기기, 필드 옮기기, 여러 함수를 클래스로 묶기, 여러 함수를 변환 함수로 묶기, 단계 쪼개기, 함수 인라인하기, 클래스 인라인하기
상속 포기메서드 내리기, 필드 내리기, 서브 클래스를 위임으로 바꾸기, 슈퍼클래스를 위임으로 바꾸기
서로 다른 인터페이스의 대안 클래스들함수 선언 바꾸기, 함수 옮기기, 슈퍼클래스 추출하기
성의 없는 요소함수 인라인하기, 클래스 인라인하기, 계층 합치기
임시 필드클래스 추출하기, 함수 옮기기, 특이 케이스 추가하기
전역 데이터변수 캡슐화하기
주석함수 추출하기, 함수 선언 바꾸기, Assertion 추가하기
중개자중개자 제거하기, 함수 인라인하기, 서브클래스 위임으로 바꾸기, 슈퍼클래스 위임으로 바꾸기
중복 코드함수 추출하기, 문장 슬라이드하기, 메서드 올리기
추측성 일반화계층 합치기, 함수 인라인하기, 클래스 인라인하기, 함수 선언 바꾸기, 죽은 코드 제거하기

기이한 이름

함수 이름은 동작 방식이 아닌 의도가 드러나게 짓는다.

  • 코드는 단순하고 명료하게 작성해야 한다.
  • 함수 선언 바꾸기
  • 변수 이름 바꾸기
  • 필드 이름 바꾸기

중복 코드

  • 함수 추출하기
  • 문장 슬라이드하기
  • 메서드 올리기

긴 함수

무엇을 하는지 코드가 잘 설명해주지 못할수록 함수로 만드는게 유리하다.

  • 함수 추출하기
  • 임시 변수를 질의 함수로 바꾸기
  • 매개변수 객체 만들기, 객체 통째로 넘기기
  • 함수를 명령으로 바꾸기
  • 조건문 분해하기
  • 조건부 로직을 다형성으로 바꾸기
  • 반복문 쪼개기

긴 매개변수 목록

  • 매개변수를 질의 함수로 바꾸기
  • 객체 통째로 넘기기
  • 매개변수 객체 만들기
  • 여러 함수를 클래스로 묶기
    • 함수형 프로그래밍이라면, 부분 적용 함수

전역 데이터

클래스 변수와 싱글톤에서 문제가 많이 발생한다.

  • 변수 캘슐화하기

가변 데이터

  • 변수 캡슐화 하기
  • 변수 쪼개기
  • 문장 슬라이드하기, 함수 추출하기
  • 세터 제거하기
  • 파생 변수를 질의 함수로 바꾸기
  • 여러 함수를 클래스로 묶기, 여러 함수를 변환 함수로 묶기
  • 참조를 값으로 바꾸기

뒤엉킨 변경

코드를 수정할 때는 시스템에서 고쳐야 할 딱 한 군데를 찾아서 그 부분만을 수정하면 되는 게 가장 좋다.

뒤엉킨 변경은 SRP(Single Responsibility Principle)를 위배할 경우 많이 발생한다.

  • 단계 쪼개기
  • 함수 옮기기
  • 함수 추출하기
  • 클래스 추출하기

산탄총 수술

산탄총 수술은 뒤엉킨 변경과 비슷하면서도 정반대다.

코드를 변경할 때마다 자잘하게 수정해야하는 클래스가 많을 때 풍기는 냄새이다.

  • 함수 옮기기, 필드 옮기기
  • 여러 함수를 클래스로 묶기
  • 여러 함수를 변환 함수로 묶기
  • 단계 쪼개기
  • 함수 인라인하기
  • 클래스 인라인하기
뒤엉킨 변경산탄총 수술
원인맥락을 잘 구분하지 못함
해법 원리맥락을 명확히 구분
발생 과정한 코드에 섞여 들어감여러 코드에 흩뿌려짐
실제 해결 방법맥락별로 분리맥락별로 모음

기능 편애

기능 편애는 흔히 어떤 함수가 자기가 속한 모듈의 함수나 데이터보다 다른 모듈의 함수나 데이터와 상호작용할 일이 더 많을때 풍기는 냄새이다.

  • 함수 옮기기
  • 함수 추출하기

데이터 뭉치

  • 클래스 추출하기
  • 매개변수 객체 만들기
  • 객체 통째로 넘기기

기본형 집착

  • 기본형을 객체로 바꾸기
  • 타입 코드를 서브클래스로 바꾸기
  • 조건부 로직을 다형성으로 바꾸기
  • 클래스 추출하기
  • 매개변수 객체 만들기

반복되는 switch문

중복된 switch문이 문제가 되는 이유는 조건절을 하나 추가할 때 마다 다른 swtich문들도 모두 찾아서 함께 수정해야하기 때문이다.

  • 조건부 로직을 다형성으로 바꾸기

반복문

  • 반복문을 파이프라인으로 바꾸기
    • 일급 함수

성의 없는 요소

  • 함수 인라인하기, 클래스 인라인 하기
  • 계층 합치기

추측성 일반화

“나중에 필요할거야”라는 생각으로 당장은 필요 없는 모든 종류의 후킹 포인트와 특이 케이스 처리 로직을 작성해둔 코드에서 풍기는 냄새이다.

  • 계층 합치기
  • 함수 인라인하기, 클래스 인라인 하기
  • 함수 선언 바꾸기
  • 죽은 코드 제거하기
    • 테스트 코드 말고는 사용하는 함수나 클래스 제거
    • 테스트 케이스부터 삭제한 뒤, 죽은 코드 제거

임시 필드

간혹 특정 상황에서만 값이 설정되는 필드를 가진 클래스도 있다.

  • 클래스 추출하기
  • 함수 옮기기
  • 특이 케이스 추가하기

메시지 체인

  • 위임 숨기기
  • 함수 추출하기
  • 함수 옮기기

중개자

  • 중개자 제거하기
    • 일부는 디미터의 법칙의 예외를 허용해주자.
  • 함수 인라인하기

내부자 거래

모듈 사이의 데이터 거래가 많으면 결합도(Coupling)가 높아진다고 투덜댄다.
일이 돌아가게 하려면 거래가 이뤄질 수 밖에 없지만, 그 양을 최소로 줄이고 모두 투명하게 처리해야 한다.

  • 함수 옮기기, 필드 옮기기
  • 위임 숨기기
  • 서브클래스를 위임으로 바꾸기, 슈퍼클래스를 위임으로 바꾸기

거대한 클래스

한 클래스가 너무 많은 일을 하려다 보면 필드 수가 상당히 늘어난다.
그리고 클래스에 필드가 너무 많으면 중복 코드가 생기기 쉽다.

  • 클래스 추출하기
  • 슈퍼클래스 추출하기
  • 타입 코드를 서브클래스로 바꾸기
  • 클래스 추출하기, 슈퍼클래스 추출하기

서로 다른 인터페이스의 대안 클래스들

  • 함수 선언 바꾸기
  • 함수 옮기기
  • 슈퍼클래스 추출하기

데이터 클래스

데이터 클래스란 데이터 필드와 Getter/Setter 메서드로만 구성된 클래스를 말한다.

  • 레코드 캡슐화하기
  • 세터 제거하기
  • 함수 옮기기
  • 함수 추출하기

상속 포기

  • 메서드 내리기, 필드 내리기
  • 서브클래스를 위임으로 바꾸기, 슈퍼클래스를 위임으로 바꾸기

주석

주석을 남겨야겟다는 생각이 들면, 가장 먼저 주석이 필요 없는 코드로 리팩터링하라!

  • 함수 추출하기
  • 함수 선언 바꾸기
  • Assertion 추가하기
profile
Hello velog!

0개의 댓글