리팩터링/리팩터링 기법

리팩터링 기법. 질의 함수와 변경 함수 분리하기(Separate Query from Modifier)

developer-tj 2023. 3. 12. 12:00
반응형

질의 함수와 변경 함수 분리하기(Separate Query from Modifier)는 함수가 값을 반환하면서 동시에 인자를 수정하는 것을 분리하는 리팩터링 기법입니다.
이를 통해 가변 데이터 문제를 해결할 수 있습니다.

보통 함수는 인자를 받아서 일부 처리를 수행하고, 결과를 반환하는 것이 일반적입니다.
하지만 때로는 함수가 값을 반환하면서 동시에 인자를 수정하는 경우가 있습니다.
이 경우 함수를 호출할 때마다 다른 결과를 얻을 수 있기 때문에 예측하기 어렵고, 디버깅도 어렵습니다.

질의 함수와 변경 함수 분리하기를 적용하면 이러한 문제를 해결할 수 있습니다.
함수를 두 개로 분리하여 값을 반환하는 함수와 값을 수정하는 함수로 나누는 것입니다.
이렇게 하면 값을 수정하는 함수를 호출할 때는 인자만 변경되고 반환 값은 받지 않으므로, 예측하기 쉽고 디버깅도 쉬워집니다.


예를 들어 다음과 같은 함수가 있다고 가정해봅시다.


int getTotalOutsandingAndSendBill()
{
    const int restul = std::reduce(customer.begin(), customer.end(), 0, [](int total, Customer a)
        {
            return total + a.amout;
        });
    sendBill();
    return result;
}


위 코드에서는 getTotalOutsandingAndSendBill() 함수에서 TotalOutsanding 값을 구하고 동시에 청구서(bill)을 보냅니다.

질의 함수와 변경 함수 분리하기를 사용하여 다음과 같이 리팩터링합니다.


int getTotalOutstanding()
{
    return std::reduce(customer.begin(), customer.end(), 0, [](int total, Customer a)
        {
            return total + a.amout;
        });
}

void sendBill()
{
    // 청구서를 보내는 로직
}

void printTotalOutstanding()
{
    const int total = getTotalOutstanding();
    std::cout << "Total outstanding: " << total << '\n';
    sendBill();
}


변경된 코드에서 getTotalOutstanding() 함수는 단순히 계산만 하고, 어떤 상태도 변경하지 않습니다. sendBill() 함수는 이름 그대로 청구서를 보내는 역할을 하며, printTotalOutstanding() 함수에서는 getTotalOutstanding() 함수를 호출하여 계산한 값을 출력하고, sendBill() 함수를 호출하여 청구서를 보냅니다. 이렇게 함수의 역할을 분리함으로써, 함수 간의 의존성이 줄어들고 코드 유지보수가 용이해집니다.