호출하는 쪽이 함수 안에서 실행할 로직을 고르려고 넘기는 인수. 호출문만 봐서는 무슨 뜻인지 알기 어렵고, 함수가 어떤 기능들을 제공하는지도 숨긴다.
// before
deliveryDate(order, true) // true가 뭐지?
// after
rushDeliveryDate(order)
regularDeliveryDate(order)- 문제는 불리언 자체가 아니라 리터럴로 넘긴다는 점이다.
deliveryDate(order, isRush)처럼 데이터에서 계산된 값을 넘기는 건 괜찮다 - 분기가 함수 맨 위에서 갈린다면 함수를 둘로 나눈다. 안쪽 깊이 얽혀 있다면
rushDeliveryDate = o => deliveryDate(o, true)같은 감싸는 함수를 만들고 원래 함수는 직접 부르지 못하게 한다 - 플래그가 둘 이상이면 조합 수만큼 함수를 만들기 어려워 플래그를 쓸 핑계가 되지만, 그 자체가 함수가 너무 많은 일을 한다는 신호이기도 하다
- 반대 방향 리팩터링도 있다. 리터럴 값만 다른 비슷한 함수들(
tenPercentRaise,fivePercentRaise)은 값을 매개변수로 받는 하나의 함수로 합친다(함수 매개변수화하기, Parameterize Function)
React 컴포넌트의 isPrimary, isLarge 같은 불리언 prop이 늘어날 때도 같은 냄새가 난다. variant 같은 값 하나나 컴포넌트 합성으로 바꾸는 편이 낫다. 긴 매개변수 목록의 다른 처방은 매개변수 객체 만들기.
출처: 『리팩터링 2판』 마틴 파울러 (원서 Refactoring, 2nd Edition) · refactoring.com: Remove Flag Argument · Martin Fowler: Flag Argument · Refactoring.Guru: Replace Parameter with Explicit Methods