alt
Home 리팩터링 8장. 기능 이동
Post
Cancel

리팩터링 8장. 기능 이동

: 어떠한 요소를 다른 컨텍스트(클래스, 모듈 혹은 코드 라인)로 옮기는 방식의 리팩터링.


1. 함수 옮기기

  • 모듈성을 높이기 위해 연관된 요소들끼리 묶는다. -> 모듈을 잘 분리하면 응집도가 높은 코드가 되고 캡슐화가 좋아진다.
    • 프로그램 언어마다 모듈화 수단이 다르다. 자바의 경우 객체지향의 패러다임을 가지며, 따라서 핵심 모듈화 컨택스트 단위는 클래스이다.
    • 리팩터링하고자하는 프로그램의 이해도가 높을수록 요소들을 잘 묶는 방법을 알 수 있다.


2. 필드 옮기기

  • 데이터 구조가 주어진 문제에 적합하게 잘 설계되어있다면 보통 동작 코드단순하고 직관적인 코드가 된다.
  • 데이터 구조는 곧 클래스의 필드들이기 때문에 각 클래스에는 필요한 필드들로 잘 구성되어있어야 한다. 그런데, 초기 설계에서 적절한 데이터 구조를 가져가도록 구성하는 것이 쉽지 않다. 객체지향이 어려운 이유 중 하나이며, 잘못됨을 깨달을 때 항상 수정을 해 개선해야한다.


3. 문장을 함수로 옮기기

: 특정 함수를 호출하는 부분 전후로 특정 코드가 항상 반복되는 경우, 해당 문장을 함수 내부로 옮길 수 있을지를 고민한다. 이 때는 해당 문장이 그 함수의 일부분이라는 확신이 있어야한다. 이렇게하면 수정이 필요할 때 해당 메서드만 고치면 된다.


4. 문장을 호출한 곳으로 옮기기

  • 초기에는 한 가지 일만 수행하던 함수가 둘 이상의 일을 수행하게 변할 수 있다.
    • SRP가 깨지는 상황이 되며, 코드의 응집도는 낮아진다. 이 경우 문장을 호출한 곳으로 옮기는 리팩터링을 적용한다.


5. 인라인 코드를 함수 호출로 바꾸기

  • 인라인 코드를 함수 호출로 바꾸면 네이밍을 통해 해당 코드 호출의 목적을 보다 명확히 알 수 있다.
  • 수정이 필요할 때 함수 한군데만 수정하면 된다. 이 때 모든 호출부가 수정된 코드를 원하는지를 확인해야하지만 보통은 그런 경우가 많지 않다. 만약 그런 경우라면 함수의 목적이 원래의 인라인 코드와 목적이 다른 경우이다. (우발적 중복) 이 때라면 별도의 함수로 두고 네이밍을 다르게 두는게 맞아보인다.


6. 문장 슬라이드하기

: 주로 다른 리팩터링의 준비단계로, 관련 코드를 한군데로 모으는 작업이다. 주의해야 할 점은 side effect가 존재하는 코드는 좀더 주의를 기울이고, 꼭 테스트를 하면서 리팩터링을 해야한다.


7. 반복문 쪼개기

  • 한 반복문 내에서 두가지 일을 수행한다면 해당 함수는 서로 다른 일들이 수행되고 있을 확률이 높다. 대개 반복문을 쪼개고 난 시점에는 함수 추출하기를 수행할 수 있고, 그 후 파이프라인으로 바꾸기를 수행할 수 있다.
  • 최적화에 대한 고민 : 대부분의 경우 n번의 loop를 2 * n번으로 바꾼다고해서 성능이 달라지는 경우는 드물다. 리팩터링을 끝낸 후 벤치마크 테스트를 해 비교를해도 된다. 그 시점에 다시 합치는 것은 쉬운 일이다.


8. 반복문을 파이프라인으로 바꾸기

: filter, map 등의 연산을 통해 논리 흐름을 표현할 수 있어 코드를 이해하기에 좋아보인다. 또, 최근에는 많은 언어들이 함수형 프로그래밍을 지향하면서 Side effect를 줄이는 방식의 개발을 지향하는데, 그러한 측면에서도 가능하다면 최신의 방식을 택하는 것이 적합해보인다.


9. 죽은 코드 제거하기

: deprecated되고 해당 코드의 클라이언트가 없다는 확신이 있으면 과감히 지우면 된다. 혹시나 미래에 해당 코드가 필요하다면 형상관리 툴을 통해 히스토리를 보면 된다.



Reference)

리팩터링 2판

This post is licensed under CC BY 4.0 by the author.

리팩터링 7장. 캡슐화

리팩터링 9장. 데이터 조직화