본문 바로가기
JavaScript│Node js

마틴 파울러 - 리팩토링 - Split Phase

by 자유코딩 2019. 10. 18.

리팩토링 기법. Split Phase


const orderData = { orderString.split(/\s+/ );
const productPrice = priceList[orderData[0].split("-")[1]];
const orderPrice = parseInt(orderData[1]) * productPrice;

const orderRecord = parseOrder(order);
const orderPrice = price(orderRecord, priceList);

function parseOrder(aString) {
	const values = aString.split(/\s+/);
    return ({
    	productID: values[0].split("-")[1],
        quantity: parseInt(values[1]),
    });
}
function price(order, priceList) {
	return order.quantity * priceList[order.producID];
}

 

규모가 큰 프로그램에서 코드를 분리하는 것은 유용하다.

코드를 작업 별로 나눠놓지 않으면 한번에 여러개의 문제를 생각해야 할 수도 있다.

작업을 순차적으로 나누고 함수로 구성하면 한번에 한 개의 문제에만 집중 할 수 있다.

 

나누는 과정은 이렇다.

아래 코드를 Split Phase를 사용해서 나눠보겠다.

function priceOrder(product, quantity, shippingMethod) {
	const basePrice = product.basePrice * quantity;
    const discount = Math.max(quantity - product.discountThreshold, 0)
    		* product.basePrice * product.discountRate;
	const shippingPerCase = (basePrice > shippingMethod.discountThreshold)
    	? shippingMethod.discountedFee : shippingMethod.feePerCase;
    const shippingCost = quantity * shippingPerCase;
    const price = basePrice - discount + shippingCost;
    return price;
}

먼저 코드를 1번째 단계와 2번째 단계로 분리한다.

 

function priceOrder(product, quantity, shippingMethod) {
	const basePrice = product.basePrice * quantity;
    const discount = Math.max(quantity - product.discountThreshold, 0)
    		* product.basePrice * product.discountRate;
    const price = applyShipping(basePrice, shippingMethod, quantity, discount);
    return price;
}

shipping 에 관련된 부분을 2번째 단계로 추출한다.

 

function applyShipping(basePrice, shippingMethod, quantity, discount) {
	const shippingPerCase = (basePrice > shippingMethod.discountThreshold)
    	? shippingMethod.discountedFee : shippingMethod.feePerCase;
    const shippingCost = quantity * shippingPerCase;
    const price = basePrice - discount + shippingCost;
    return price;
}

 

----------------------------------------------------------------------------

 

그 다음 첫번째 단계에 변수를 만든다.

 

function priceOrder(product, quantity, shippingMethod) {
	const basePrice = product.basePrice * quantity;
    const discount = Math.max(quantity - product.discountThreshold, 0)
    		* product.basePrice * product.discountRate;
    const priceData = {};
    const price = applyShipping(priceData, basePrice, shippingMethod, quantity, discount);
    return price;
}

 

priceData라는 빈 변수를 선언했다.

이제 두번째 단계의 함수에서 priceData를 매개변수로 쓴다.

function applyShipping(priceData, basePrice, shippingMethod, quantity, discount) {
	const shippingPerCase = (basePrice > shippingMethod.discountThreshold)
    	? shippingMethod.discountedFee : shippingMethod.feePerCase;
    const shippingCost = quantity * shippingPerCase;
    const price = basePrice - discount + shippingCost;
    return price;
}

이제 applyShipping 함수의 매개변수를 basePrice 부터 하나씩 살핀다.

하나씩 priceOrder에서도 사용되는지 살펴본다.

priceOrder 함수에서도 쓰인다면 priceData객체에 추가한다.

 

----------------------------------------------------------------------------

 

function priceOrder(product, quantity, shippingMethod) {
const basePrice = product.basePrice * quantity;
    const discount = Math.max(quantity - product.discountThreshold, 0)
     * product.basePrice * product.discountRate;
    const priceData = { basePrice: basePrice, quantity: quantity, discount:discount };
    const price = applyShipping(priceData, basePrice, shippingMethod, quantitydiscount);
    return price;
}

이렇게 옮기면 아래 코드처럼 된다.

function priceOrder(product, quantity, shippingMethod) {
	const basePrice = product.basePrice * quantity;
    const discount = Math.max(quantity - product.discountThreshold, 0)
     * product.basePrice * product.discountRate;
    const priceData = { basePrice: basePrice, quantity: quantity, discount:discount };
    const price = applyShipping(priceData, shippingMethod);
    return price;
}

 

function applyShipping(priceData, basePrice, shippingMethod, quantity) {
	const shippingPerCase = (basePrice > shippingMethod.discountThreshold)
    	? shippingMethod.discountedFee : shippingMethod.feePerCase;
    const shippingCost = quantity * shippingPerCase;
    const price = priceData.basePrice - priceData.discount + shippingCost;
    return price;
}

 

 

-----------------------------------------------------------------------------------------------

여기서 첫번째 페이즈의 price를 계산하는 부분이랑 discount 계산하는 부분도 나눌 수 있다.

 

function priceOrder(product, quantity, shippingMethod) {
	const priceData = calculatePricingData(product, quantity);
    const price = applyShipping(priceData, shippingMethod);
    return price;
}

discount 하는 부분을 아래처럼 빼냈다.

function calculatePricingData(product, quantity) {
	const basePrice = product.basePrice * quantity;
    const discount = Math.max(quantity - product.discountThreshold, 0)
    	* product.basePrice * product.discountRate;
    return { basePrice: basePrice, quantity: quantity, discount: discount };
}

 

function applyShipping(priceData, shippingMethod) {
	const shippingPerCase = (priceData.basePrice > shippingMethod.discountThreshold)
    	? shippingMethod.discountedFee : shippingMethod.feePerCase;
    const shippingCost = priceData.quantity * shippingPerCase;
    const price = priceData.basePrice - priceData.discount + shippingCost;
    return price;
}

 

-----------------------------------------------------------------------------------------------

temp variable 을 정리하면 끝난다.

return 만을 위해서 쓰이는 맨아래 있는 price 변수를 없앤다.

 

function priceOrder(product, quantity, shippingMethod) {
	const priceData = calculatePricingData(product, quantity);
    return applyShipping(priceData, shippingMethod);
}
function calculatePricingData(product, quantity) {
	const basePrice = product.basePrice * quantity;
    const discount = Math.max(quantity - product.discountThreshold, 0)
    	* product.basePrice * product.discountRate;
    return { basePrice: basePrice, quantity: quantity, discount: discount };
}
function applyShipping(priceData, shippingMethod) {
	const shippingPerCase = (priceData.basePrice > shippingMethod.discountThreshold)
    	? shippingMethod.discountedFee : shippingMethod.feePerCase;
    const shippingCost = priceData.quantity * shippingPerCase;
    return priceData.basePrice - priceData.discount + shippingCost;
}

 

댓글