08. 기능 이동
8.1 함수 옮기기#
- 좋은 설계의 핵심은 모듈화가 얼마나 잘되어 있는가를 뜻하는 
모듈성이다- 모듈성은 수정할 때 관련 기능과 깊이를 작은 일부만 이해해도 가능하게 해주는 능력
 
 - 프로그램의 이해도가 높아질수록 요소들을 더 잘 묶는 새로운 방법을 알게됨
 - 객체 지향 프로그래밍의 핵심 모듈화 컨텍스트는 클래스
 - 필요에 따라 새로운 컨텍스트를 만들어야할 때도 있음
 
함수를 옮겨야 하는 신호#
- 어떤 함수가 자신이 속한 A 요소보다 B 요소를 더 많이 참조할 때
 - 다음 업데이트 때 바뀌리라 예상되는 위치가 생각날 때
 
옮길 장소를 정하기 어려울 때#
- 옮겨야 할 대상 함수의 현재 컨텍스트와 후보 컨텍스트를 둘러보면 도움
 - 살펴보면 도움되는 요소
- 대상 함수를 호출하는 곳
 - 대상 함수가 호출하는 함수들
 - 대상 함수가 사용하는 데이터
 
 - 정 어려우면 한 컨텍스트에 일단 몰아보기, 이후 인사이트를 얻을 확률이 높음
 
함수 옮기기 리팩터링 절차#
- 옮길 대상 함수가 현재 컨텍스트에 사용 중인 모든 프로그래밍 요소를 살펴보기. 요소 중 같이 옮길 것이 있는지 고민
 - 선택한 함수가 다형 메서드인지 확인 (같이 옮겨줘야 하므로)
 - 옮겨질 컨텍스트(target context)로 선택한 함수를 복붙. 타겟 함수가 타겟 컨텍스트에 어울리도록 다듬기 (이름변경, 파라미터 변경 등)
- target function: 복붙된 함수
 - source function: 기존 옮겨질 대상 함수
 
 - 정적 분석
 - 소스 컨텍스트에 타겟 함수를 참조할 방법을 찾아 반영
 - 소스 함수를 타겟 함수의 위임 함수가 되도록 수정
 - 테스트
 - 소스 함수를 인라인할지 고민
- 제거하는 편이 맞지만 너무 많은 의존성이 있으면 다 파악하기 어려움
 
 
8.2 필드 옮기기#
- 프로그램의 진짜 힘은 데이터 구조에서 나온다
 - 데이터 구조를 잘못 선택하면
- 아귀가 맞지 않는 데이터를 다루기 위한 코드로 범벅
 - 데이터 구조 자체의 역할도 파악하기 어려움
 
 - 경험과 도메인 주도 설계 같은 기술이 가장 적합한 데이터 구조를 만들어낼 때 도움
 - 현재 데이터 구조가 적절치 않음을 깨달으면 바로 수정
 
필드를 옮겨야하는 신호#
- 함수에 어떤 레코드를 옮길 때 마다 따라 붙는 필드가 있을 때
 - 한 레코드를 변경하려 할 때 다른 레코드도 변경할 때
 
필드 옮기기 리팩터링 절차#
- 소스 필드가 캡슐화되어 있지 않다면 캡슐화
 - 테스트
 - 타겟 객체에 필드, 접근자 메서드 생성
 - 정적 검사
 - 소스 객체에 타겟 객체를 참조할 수 있는지 확인
- 간단치 않다면 타겟 객체를 저장할 새필드를 소스 객체에 생성
 
 - 접근자들이 타겟 객체를 사용하도록 수정
 - 테스트
 - 소스 필드 제거
 - 테스트
 
8.3 문장을 함수로 옮기기#
Move Statements into Function
- 문장이라고 표현해서 헷갈리는데, 여기서 말하는 문장은 Statement 라고 해석하자
 - 중복 제거 방법 중 하나
 - 해당 리팩터링을 했는데 여러 변형이 다시 나눠야하는 순간이 오면 다시 역으로 문장을 호출하는 곳으로 옮기면 된다 (8.4)
 - 문장을 함수로 옮기려면 대상 함수의 일부라는 확신이 있어야함
 - 애매하다면 매당 문장들과 피함수를 통째로 하나의 함수로 추출할 수 있다 (6.1)
 
문장을 함수로 옮겨야하는 신호#
- 특정 함수를 호출하는 코드가 나올 때 마다 그 앞이나 뒤에 똑같은 코드가 발생할 때
 
8.4 문장을 호출한 곳으로 옮기기#
Move Statements to Callers
- 8.3 과 반대 리팩터링
 - 초기엔 응집도가 높고 한 가지 일만 수행하던 함수가 둘 이상의 다른 일을 수행하게 바뀔 수 있다
 - 단순하게는 호출자로 일부 문장을 넘길 수 있다
 - 책임이 불분명해지거나 할 땐, 호출자와 호출 대상의 경계를 다시 그어야 할 때도 있음
- 이럴 땐 함수 인라인 (6.2) 후, 문장 슬라이드 (8.6) + 함수 추출하기 (6.1) 로 더 적합한 경계를 설정할 수 있다
 
 
문장을 호출한 곳으로 옮겨야 하는 신호#
- 한가지 일을 수행하던 함수가 둘 이상의 다른 일을 수행하게 될때 고려 가능
 - 여러 곳에서 사용하던 함수가 일부 호출자에서 다르게 동작하도록 바뀌어야 할 때