Written by
Jiyun Wang
on
on
코드 리팩터링 2판, 6-1. 함수 추출하기
하루에 한 챕터씩 읽고 정리해보기 도전!
6. 기본적인 리팩토링
6.1 함수 추출하기(반대 : 함수 추출하기)
- 배경
- 함수 추출하기 -> 코드 조각을 찾아 무슨 일을 하는지 파악한 다음, 독립적인 함수로 추출하고 목적에 맞는 이름을 붙인다.
- 기준은 어떻게 해야할까?
- 길이를 기준으로 삼던지, 재사용성으로 판단할 수도 있다.
- 목적과 구현을 분리 -> 코드를 보고 무슨 일을 하는지 파악하는데 한참이 걸린다면 그 부분을 함수로 추출하고 “무슨 일”에 걸맞는 이름을 짓는다.
- 함수를 아주 짧게 작성해도 좋다. 몇 줄 또는 단 한 줄 이어도 좋다. 길이가 중요하기 보다는 함수를 바로 이해할 수 있도록 분리하고 네이밍을 짓는 것이 더 중요하다.
- 대여섯 줄을 넘어갈 때 부터 슬슬 풍기는 냄새…
- 함수를 짧게 만들면 성능이 느려질까 걱정한다면?
- 함수가 짧으면 캐싱하기가 더 쉽기 떄문에 컴파일러가 최적화하는데 오히려 유리할 수 있다.
- 절차
- 함수를 새로 만들고 목적을 잘 드러내는 이름을 붙인다. (“무엇을” 하는지?)
- 일단 함수로 뽑아서 목적이 더 잘 드러나는 이름을 붙일 수 있다면 추출한다. 이름이 잘 떠오르지 않는다면 함수로 추출하면 안 된다는 신호다.
- 추출할 코드를 원본 함수에서 복사하여 새 함수에 붙여넣는다.
- 추출한 코드 중 원본 함수의 지역 변수를 참조하거나 추출한 함수의 유효범위를 벗어나는 변수는 없는지 검사한다. 있다면 매개변수로 전달한다.
- 일반 적인 방법은 변수를 모두 인수로 전달하는 것이다.
- 추출한 코드 내에서만 사용하는 변수가 추출한 함수 밖에 있다면 이를 함수 안에서 선언하여 사용하도록 수정한다.
- 변수를 다 처리했다면 컴파일한다.
- 제대로 처리하지 못한 것이 있는지 찾아볼 수 있다.
- 원본 함수에서 추출한 코드 부분을 새로 만든 함수를 호출하는 문장으로 바꾼다.
- 테스트한다.
- 다른 코드에 방금 추출한 것과 똑같거나 비슷한 코드가 없는지 살핀다. 방금 추출한 함수를 호출하도록 바꿀지 검토한다.
- 함수를 새로 만들고 목적을 잘 드러내는 이름을 붙인다. (“무엇을” 하는지?)
- 예시
- 유효범위를 벗어나는 변수가 없을 때
- 그냥 해당 코드를 잘라내어 함수로 분리하고 코드 상에서 해당 함수를 호출하도록 변경한다. (가장 쉬움)
- 지역 변수를 사용할 때
- 지역 변수들을 그냥 매개변수로 넘긴다.
- 지역 변수의 값을 변경할 때 (아래 예시 코드 흐름에 따라 설명한다.)
- 절차
- 선언문을 변수가 사용하는 코드 근처로 슬라이스
- 추출할 부분을 새로운 함수로 복사
- 변경된 변수가 있다면 함수에서 반환
- 원래 코드를 함수 호출하는 문장으로 교체
- 이름은 내 코딩 스타일에 맞게 변경
-
예시
total_price = 0 print("a") # total_price와 무관한 로직들 print("b") # total_price와 무관한 로직들 for product in product_list: total_price += product.price1) 변수가 추출된 코드 안에서만 사용이 되는 경우, 매개변수에 값을 대입하는 코드를 발견하면 변수를 쪼개서 임시 변수를 새로 하나 만들어 그 변수에 대입한다. 만약 변수가 초기화되는 지점과 사용되는 지점이 떨어져있는 경우 “문장 슬라이스하기”를 사용하여 한곳에서 처리하도록 한다. (아래 코드 예시)
print("a") # total_price와 무관한 로직들 print("b") # total_price와 무관한 로직들 total_price = 0 # 코드 근처로 슬라이스 (문장 슬라이스) for product in product_list: total_price += product.price2) 변수가 추출된 코드 밖에서 사용이 되는 경우, 변수에 대입된 새 값을 반환해야 한다.(아래 코드 예시)
print("a") # total_price와 무관한 로직들 print("b") # total_price와 무관한 로직들 # 위와 같이 함수로 분리 + 변수에 대입된 새 값을 리턴하도록 total_price = sum_price(product_list) # 아예 분리된 함수라고 가정. def sum_price(product_list): total_price = 0 for product in product_list: total_price += product.price return total_price
- 절차
- 유효범위를 벗어나는 변수가 없을 때