액션에서 암묵적 입력과 출력을 줄여 설계를 개선하는 방법에 대해 알아보자.

비즈니스 요구 사항과 설계를 맞추기

Untitled

요구 사항에 맞춰 더 나은 추상화 단계 선택하기

기존 코드에서 요구사항에 맞지 않은 부분

장바구니에 담긴 제품을 주문할 때 무료 배송인지 확인하는 함수 gets_free_shipping()

→ 장바구니로 무료 배송을 확인하는 게 아니라 제품의 합계와 가격으로 확인하고 있다.

                            // 인자가 요구사항이랑 맞지 않는다				
function gets_free_shipping(total, item_price) {
  return item_price + total >= 20
         // 장바구니 합계 계산
}

중복된 코드도 존재. 아래 위 코드에 합계에 제품 가격을 더하는 코드가 두 군데나 있다.

function calc_total(cart) {
  var total = 0
  for(var i = 0; i < cart.length; i++) {
    var item = cart[i]
    total += item.price
    // 장바구니 합계 계산
  }
  return total
}

비즈니스 요구 사항과 함수를 맞추기

함수의 동작을 바꿨으므로 엄밀한 의미의 리팩터링은 아니다.

function update_shopping_icons() {
  var buy_buttons = get_buy_buttons_dom()
  for (var i = 0; i < buy_buttons.length; i++) {
    var button = buy_buttons[i]
    var item = button.item
    if (gets_free_shipping(shopping_cart_total, item.price)) {
      button.show_free_shopping_icon()
    } else {
      button.hide_free_shopping_icon()
    }
  }
}

function gets_free_shipping(total, item_price) {
  return item_price + total >= 20
}
function update_shopping_icons() {
  var buy_buttons = get_buy_buttons_dom()
  for (var i = 0; i < buy_buttons.length; i++) {
    var button = buy_buttons[i]
    var item = button.item
    // 새 아이템 추가하여 새 장바구니 만듦
    var new_cart = add_item(shopping_cart, item.name, item.price)
    if (gets_free_shipping(new_cart)) {
      button.show_free_shopping_icon()
    } else {
      button.hide_free_shopping_icon()
    }
  }
}

function gets_free_shipping(cart) {
	return calc_total(cart) >= 20
}

이제 gets_free_shipping()은 장바구니 자체가 무료배송인지 여부를 알려준다.

원래 있던 장바구니를 직접 변경하지 않고 복사본을 만들었다. 이런 스타일을 카피 온 라이트 copy-on-write라 한다.