Skip to content

액션의 암묵적 의존성을 최소화하기 ​

이전 장에서는 액션에서 암묵적 입력과 출력을 제거해 계산으로 바꿔보았습니다. 하지만 프로그램에서 액션은 반드시 필요하기 때문에 이런 방식으로 모든 액션을 없앨 수는 없습니다.

대신, 액션에서 암묵적 입력과 출력을 줄여 설계를 개선할 수 있습니다. 이번 장에서는 액션을 완전히 제거하는 것이 아니라, 액션이 가진 암묵적 의존성을 최소화하는 방법을 살펴보겠습니다.

1. 암묵적 입력과 출력을 줄여야 하는 이유 ​

어떤 함수가 암묵적 입력·출력을 가진다면, 그 함수는 다른 컴포넌트와 강하게 연결됩니다. 예를 들어, 장바구니의 총액을 계산하는 아래 함수를 보겠습니다.

tsx
function calculateCartTotal() {
    // 암묵적 입력: 전역 변수 shopping_cart 읽기
    let total = 0;
    for (let item of shopping_cart) {
        total += item.price;
    }

    // 암묵적 출력: DOM 업데이트
    updateTotalDisplay(total);

    return total;
}

이 함수가 실행되는 동안은, 전역 변수 shopping_cart 값이 바뀌어서는 안 됩니다. 또 어떤 경우에는 단순히 총액만 필요할 뿐 DOM 업데이트는 원하지 않을 수도 있습니다.

즉, 암묵적 입력과 출력은 함수의 사용 범위를 좁히고 실행을 제한하는 요인이 됩니다.

2. 엉켜 있는 코드 풀어내기 ​

복잡하게 얽힌 함수를 개선하는 방법은 작은 단위로 나누는 것입니다. 이렇게 분리하면 다음과 같은 장점이 있습니다.

  1. 재사용성: 작을수록 하는 일이 적어 여러 곳에서 다시 쓸 수 있습니다.
  2. 유지보수성: 코드가 단순해져 이해하기 쉽습니다.
  3. 테스트 용이성: 한 가지 일만 담당하기 때문에 테스트가 쉽습니다.

2.1 실제로 분리하기 ​

장바구니에 제품을 추가하는 함수를 보겠습니다.

tsx
function add_item(cart, name, price) {
    var new_cart = cart.slice(); // 1. 배열 복사
    new_cart.push({
        // 2. 아이템 객체 생성 후 추가
        name,
        price,
    });
    return new_cart; // 3. 복사본 반환
}

add_item(shopping_cart, "shoes", 3.45);

겉보기에는 간단하지만, 이 함수는 여러 동작을 한꺼번에 처리하고 있습니다. 이를 더 작은 단위로 나누면 다음과 같이 정리할 수 있습니다.

tsx
// 일반적인 배열 연산으로 분리
function add_element_last(array, elem) {
    var new_array = array.slice();
    new_array.push(elem);
    return new_array;
}

// 장바구니 전용 함수로 분리
function add_item(cart, item) {
    return add_element_last(cart, item);
}

// 아이템 생성 함수도 분리
function make_cart_item(name, price) {
    return { name, price };
}

// 사용할 때
add_item(shopping_cart, make_cart_item("shoes", 3.45));

정리하며 ​

액션에서 암묵적 입력과 출력을 줄이고 계산을 분리하면 코드의 재사용성과 명확성이 높아집니다. 이는 결국 더 단단하고 유지보수하기 쉬운 프로그램 설계로 이어집니다.