개요
플래그 인수란 호출되는 함수가 실행할 로직을 호출하는 쪽에서 선택하기 위해 전달하는 인수
function bookConcert(aCustomer, isPreminum){ if(isPreminum){ // 프리미엄 예약용 로직 }else{ // 일반 예약용 로직 } } |
//호출하는 쪽 예시
bookConcert(aCustomer, true); // 불리언
bookConcert(aCustomer, Customer.PREMINUM); //열거형
bookConcert(aCustomer,"premium"); //리터럴
플래그 인수는 이렇게 호출할 수 있는 함수들이 무엇이고 어떻게 호출해야 하는지 이해하기 어려워 진다.
API를 익힐 때 함수에 플래그 인수가 있으면 함수들의 기능 차이가 잘 드러나지 않는다.
또한 함수 인자로 무엇을 넘겨야하는지 추가 학습이 필요하다.
대상 함수에게 있어서 true, false 의미가 무엇인지 명확하지 않다.
플래그 인수는 정확히 말하면 변수 형태가 아닌 리터럴 형태로 값을 건네는 것을 말한다.
리터럴이란 값 자체를 의미한다.
true , "스트링" , 123 등등…
예시
배송일자를 계산하는 호출
//도대체 이 불리언 플래그가 무슨 의미인지 알 수 있나? //호출하는 곳 1 aShipment.deliveryDate = deliveryDate(anOrder, true); //다른 어딘가 호출하는 곳2 aShipment.deliveryDate = deliveryDate(anOrder, false); function deliveryDate(anOrder, isRush){ if(isRush){ let deliveryTime; if(["MA","CT"].includes(anOrder.deliveryState)) deliveryTime = 1; else if(["NY", "NH"].includes(anOrder.deliveryState)) deliveryTime = 2; else deliveryTime = 3; return anOrder.placedOn.plusDays(1 + deliveryTime); }else{ let deliveryTime; if(["MA","CT","NY"].includes(anOrder.deliveryState)) deliveryTime = 2; else if(["ME","NH"].includes(anOrder.deliveryState)) deliveryTime = 3; else deliveryTime = 4; return anOrder.placedOn.plusDays(2 + deliveryTime); } } |
//함수 추출하기로 조건문 분해 function deliveryDate(anOrder, isRush){ if(isRush) return rushDeliveryDate(anOrder); else return regularDeliveryDate(anOrder); } function regularDeliveryDate(anOrder) { let deliveryTime; if (["MA", "CT", "NY"].includes(anOrder.deliveryState)) deliveryTime = 2; else if (["ME", "NH"].includes(anOrder.deliveryState)) deliveryTime = 3; else deliveryTime = 4; return anOrder.placedOn.plusDays(2 + deliveryTime); } function rushDeliveryDate(anOrder) { let deliveryTime; if (["MA", "CT"].includes(anOrder.deliveryState)) deliveryTime = 1; else if (["NY", "NH"].includes(anOrder.deliveryState)) deliveryTime = 2; else deliveryTime = 3; return anOrder.placedOn.plusDays(1 + deliveryTime); } |
//목적을 더 잘 드러낸다. aShipment.deliveryDate = rushDeliveryDate(anOrder); aShipment.deliveryDate = regularDeliveryDate(anOrder); function regularDeliveryDate(anOrder) { let deliveryTime; if (["MA", "CT", "NY"].includes(anOrder.deliveryState)) deliveryTime = 2; else if (["ME", "NH"].includes(anOrder.deliveryState)) deliveryTime = 3; else deliveryTime = 4; return anOrder.placedOn.plusDays(2 + deliveryTime); } function rushDeliveryDate(anOrder) { let deliveryTime; if (["MA", "CT"].includes(anOrder.deliveryState)) deliveryTime = 1; else if (["NY", "NH"].includes(anOrder.deliveryState)) deliveryTime = 2; else deliveryTime = 3; return anOrder.placedOn.plusDays(1 + deliveryTime); } |
저자가 플래그 인수를 싫어하는 이유
변수가 같은 데이터가 아니라 리터럴로 설정하기 때문이다.
const isRush = determineIfRush(anOrder);
aShipment.deliveryDate = deliveryDate(anOrder, isRush);
예시:매개변수를 까다로운 방식으로 사용할 때
function deliveryDate(anOrder, isRush){ let result; let deliveryTime; if(anOrder.deliveryState === "MA" || anOrder.deliveryState === "CT") deliveryTime = isRush ? 1 : 2; else if (anOrder.deliveryState === "NY" || anOrder.deliveryState === "NH"){ deliveryTime = 2; if(anOrder.deliveryState === "NH" && !isRush) deliveryTime = 3; } else if (isRush) deliveryTime = 3; else if (anOrder.deliveryState === "ME") deliveryTime = 3; else deliveryTime = 4; result = anOrder.placeOn.plusDays(2 + deliveryTime); if(isRush) result = result.minusDays(1); return result; } |
//지나치게 까다로워 고치려면 일이 커질 것 같으면 래핑하는 함수도 고려할만 하다. function rushDeliveryDate(anOrder) {return deliveryDate(anOrder, true);} function regularDeliveryDate(anOrder) {return deliveryDate(anOrder, false);} function deliveryDate(anOrder, isRush){ let result; let deliveryTime; if(anOrder.deliveryState === "MA" || anOrder.deliveryState === "CT") deliveryTime = isRush ? 1 : 2; else if (anOrder.deliveryState === "NY" || anOrder.deliveryState === "NH"){ deliveryTime = 2; if(anOrder.deliveryState === "NH" && !isRush) deliveryTime = 3; } else if (isRush) deliveryTime = 3; else if (anOrder.deliveryState === "ME") deliveryTime = 3; else deliveryTime = 4; result = anOrder.placeOn.plusDays(2 + deliveryTime); if(isRush) result = result.minusDays(1); return result; } |
//원래플래그 함수를 호출하지 말라는 의미에서 함수 이름 변경 function rushDeliveryDate(anOrder) {return deliveryDateHelperOnly(anOrder, true);} function regularDeliveryDate(anOrder) {return deliveryDateHelperOnly(anOrder, false);} function deliveryDateHelperOnly(anOrder, isRush){ let result; let deliveryTime; if(["MA","CT"].includes(anOrder.deliveryState)) deliveryTime = isRush ? 1 : 2; else if ( ["NY","NH"].includes(anOrder.deliveryState)){ deliveryTime = 2; if(anOrder.deliveryState === "NH" && !isRush) deliveryTime = 3; } else if (isRush || anOrder.deliveryState === "ME") deliveryTime = 3; else deliveryTime = 4; result = anOrder.placeOn.plusDays(2 + deliveryTime); if(isRush) result = result.minusDays(1); return result; } |
'IT책, 강의 > 리팩터링' 카테고리의 다른 글
11 - API 리팩터링 - 매개변수를 질의 함수로 바꾸기 (0) | 2023.09.16 |
---|---|
11 - API 리팩터링 - 객체 통째로 넘기기 (0) | 2023.09.15 |
11 - API 리팩터링 - 매개변수화하기 (0) | 2023.09.13 |
11 - API 리팩터링 - 질의 함수와 변경 함수 분리하기(query and command) (0) | 2023.09.12 |
10 - 조건부 로직 간소화 - 제어 플래그를 탈출문으로 바꾸기 (0) | 2023.09.11 |