함수형 프로그래밍 스터디 1주차

2024. 1. 30. 15:23카테고리 없음

728x90
반응형

예제

 

아래의 예제 코드는 자회사에  수수료를 보내기 위한 코드이다.

sendPayout() 함수는 실제 은행 계좌로 송금하는 액션이라고 가정해보자.

/*
    계열사별 납입금 계산 후 송금
*/
function figurePayout(affiliate) {
    var owed = affiliate.sales * affiliate.commission;
    if (owed > 100) { // 100달러 이하면 송금X
        sendPayout(affiliate.bank_code, owed); //action
    }
}

/*
    자회사에 납입금을 보내는 함수
*/
function affiliatePayout(affiliates) {
    for (var a = 0; a < affiliates.length; a++) {
        figurePayout(affiliates[a]);
    }
}

function main(affiliates) {
    affiliatePayout(affiliates);
}

 

sendPayout() 함수가 액션이기 때문에 sendPayout()을 호출하는

figurePayout() 함수 또한 액션이 되고 figurePayout()을 호출하는 affiliatePayout() 함수도 액션이 된다.

이처럼 계산과 분리되지 않은 액션은 코드 전체로 퍼져나간다.

 

위 코드의 타임 라인을 그려보면 아래와 같을 것이다.

 

만일 내가 이 코드를 테스트해야한다면 아주 답답할 것 같다.

수수료를 계산하는 함수가 송금 또한 맡고 있기 때문에, 수수료를 계산하는 함수를 테스트 할때마다 실제 송금이 일어나기 때문이다.

 

그렇다면 어떻게 하면 테스트하기 좋은 코드로 바꿀 수 있을까?

 

그것은 수수료 계산과 송금을 분리하는 것이다. (계산과 액션 분리)

 

아래 그림은 계산과 액션을 분리한 타임라인이다.

 

 

납입금(수수료)를 계산하여 납입금 데이터를 만들고

납입금의 송금 여부를 판단하여 송금할 자회사와 납입금 데이터를 만들었다.

 

이후 해당 데이터로 송금을 하였다.

/*
    자회사에 납입금을 보내는 함수
*/
function affiliatePayout(affiliates) {
    //납입금 계산
    const oweds = affiliates.map(e => {
        return {
            bank_code: e.bank_code,
            owed: e.sales * e.commission
        };
    });

    //송금여부 판단
    const payoutList = oweds.filter(e => e.owed > 100);

    //송금하기
    payoutList.forEach(e => {
        sendPayout(e.bank_code, e.owed);
    });
}

function main(affiliates) {
    affiliatePayout(affiliates);
}

 

납입금 계산과 송금 여부 판단을 송금하기와 분리하여 테스트하기 좋은 코드가 되었다.

728x90
반응형