노트

함수·필드 옮기기

Move Function

설계#refactoring · 연결된 개념 8개

쉽게 말하면

함수 옮기기는 거실 서랍에 둔 국자를 부엌으로 옮기는 것과 같아요. 늘 부엌 냄비와 함께 쓰는 물건이라면 부엌에 있어야 찾기도 쉽고, 고칠 때 집 안을 다 뒤지지 않아도 돼요.

비유가 깨지는 곳 어디에 둘지 애매하면 가장 많은 데이터를 가진 쪽으로 가요. 다만 전략 패턴이나 방문자 패턴처럼 일부러 동작을 데이터에서 떼어 두는 구조도 있어요.

함수나 필드를 더 자연스러운 맥락(모듈·클래스)으로 옮기는 리팩터링. 좋은 설계의 핵심인 모듈성(Modularity), 즉 어딘가를 고칠 때 관련된 작은 부분만 이해하면 되게 하는 능력을 키운다.

  • 기능 편애(Feature Envy): 자기 모듈보다 다른 모듈의 데이터와 더 많이 대화하는 함수. 그 데이터 곁으로 옮겨 준다. 일부만 편애한다면 그 부분만 추출해서 옮긴다
  • 어디로 옮길지 애매하면 가장 많은 데이터를 가진 쪽으로 간다
  • 옮길 때는 새 위치에 복사하고, 옛 함수가 새 함수를 부르게 바꾼 뒤 테스트하고, 마지막에 옛 함수를 인라인할지 정한다
  • 필드 옮기기(Move Field): 함수를 호출할 때마다 다른 레코드의 필드를 함께 넘기거나, 한 레코드를 바꿀 때 다른 레코드도 바꿔야 한다면 필드 위치가 잘못된 것이다. 올바른 데이터 구조를 고르면 동작 코드는 저절로 단순해진다
  • 문장 몇 줄을 함수 안으로 넣거나(Move Statements into Function, 중복 제거) 호출한 곳으로 꺼내는(Move Statements to Callers, 변형이 생겼을 때) 것도 같은 축의 기법이다

전략 패턴(Strategy Pattern)이나 방문자 패턴(Visitor Pattern)처럼 일부러 이 규칙을 거스르는 구조도 있다. 핵심 원칙은 "함께 바뀌는 것을 한데 모은다"이고, 이는 곧 응집도를 높이고 결합도를 낮추는 일이다. 산탄총 수술과 뒤엉킨 변경의 주된 처방이기도 하다.

출처: 『리팩터링 2판』 마틴 파울러 (원서 Refactoring, 2nd Edition) · refactoring.com: Move Function · refactoring.com: Move Field · Refactoring.Guru: Move Method · Refactoring.Guru: Feature Envy

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 함수 선언 바꾸기

    함수의 이름이나 매개변수 목록을 바꾸는 리팩터링. 가장 자주 쓰는 리팩터링이 이름 바꾸기인 것은, 이름이 코드를 명료하게 하는 가장 큰 도구이기 때문이다.

  • 리팩터링

    겉으로 보이는 동작은 그대로 둔 채, 코드를 이해하고 고치기 쉽게 내부 구조를 바꾸는 일. 기능을 더하는 일이 아니라 다음 변경을 덜 위험하게 만드는 정리다.

  • 임시 변수를 질의 함수로 바꾸기

    계산 결과를 담아 두던 임시 변수를 그 값을 돌려주는 함수로 바꾸는 리팩터링. 긴 함수를 쪼개기 전 단계로 특히 쓸모 있다.

  • 플래그 인수

    호출하는 쪽이 함수 안에서 실행할 로직을 고르려고 넘기는 인수. 호출문만 봐서는 무슨 뜻인지 알기 어렵고, 함수가 어떤 기능들을 제공하는지도 숨긴다.

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

    for 반복문을 filter·map·reduce 같은 컬렉션 연산의 연쇄, 즉 컬렉션 파이프라인(Collection Pipeline)으로 바꾸는 리팩터링. 각 원소가 어떤 단계를 거치는지가 위에서 아래로 읽힌다.

보기 옵션