여러 함수에 늘 함께 넘겨지는 값 묶음(데이터 뭉치, Data Clumps)을 하나의 객체로 묶어 넘기는 리팩터링.
// before
amountInvoiced(startDate, endDate)
amountOverdue(startDate, endDate)
// after
type DateRange = { start: Date; end: Date }
amountInvoiced(range)
amountOverdue(range)- 매개변수 수가 줄고, 같은 묶음을 쓰는 모든 함수가 같은 이름으로 원소를 부르게 되어 일관성이 생긴다
- 묶음에 이름이 생기면 "기간 안에 포함되는가" 같은 동작이 모일 자리가 생긴다. 키워 가면 값 객체가 된다
- 데이터 뭉치인지 판별하려면 값 하나를 빼 본다. 나머지만으로 의미가 없으면 뭉치다
객체 통째로 넘기기(Preserve Whole Object)
레코드에서 값 두어 개를 꺼내 넘기는 대신 레코드 자체를 넘긴다. 함수가 필요한 값이 늘어도 시그니처가 그대로다. 단, 함수가 그 레코드 타입에 의존하게 되므로 서로 다른 모듈이라면 하지 않는다.
반대 방향의 긴장
켄트 벡의 Explicit Parameters(한국어판 "명시적인 매개변수")는 반대를 권한다. 맵을 통째로 받아 안에서 params.a, params.b를 꺼내 쓰는 함수는 무엇이 필요한지 숨기므로, 필요한 값을 명시적으로 받으라는 것이다. 묶음에 이름과 의미가 있으면 객체로, 아무 데이터나 담기는 가방이라면 명시적 인자로 가는 편이 낫다.
긴 매개변수 목록의 다른 처방은 플래그 인수와 코드 냄새 참고.
출처: 『리팩터링 2판』 마틴 파울러 (원서 Refactoring, 2nd Edition) · refactoring.com: Introduce Parameter Object · refactoring.com: Preserve Whole Object · Refactoring.Guru: Introduce Parameter Object · 『켄트 벡의 Tidy First?』 켄트 벡 (원서 Tidy First?)