dev-hamster

좋은 액션을 위해서 본문

로그/쏙쏙 들어오는 함수형 코딩

좋은 액션을 위해서

dev-hamster 2023. 3. 30. 18:27

책 '쏙쏙 들어오는 함수형 코딩' 을 읽고 정리한 내용입니다.

목차

  • 좋은 액션?
  • 암묵적인 입력과 출력을 최소화
  • 엉킨 코드 풀기

좋은 액션?

아래 코드는 순수함수이고 문제가 없어 보이는 코드입니다.

function getsFreeShipping(total, itemPrice){
      return itemPrice + total >= 20;
}

그렇다면 설계의 관점에서 이 코드는 어떨까요?
아래처럼 리팩토링 해보았습니다.

function getsFreeShipping(cart){
      return calcTotal(cart) >= 20;
}

함수의 인자를 total, itemPrice 에서 cart 로 변경했습니다. 비즈니스 관점에서 total, itemPrice를 인자로 받아 무료배송을 판단하는 것은 어색합니다. 그러나, cart를 인자로 받도록 리팩토링하여 cart로 무료배송을 판단하는 것은 자연스럽습니다.

비즈니스 규칙을 분리하면 어떤 이점이 있을까요? 비즈니스 규칙은 변경가능성이 매우 높습니다. 그러므로 비즈니스 규칙을 분리하면 비즈니스 규칙이 변경되어도 다른 코드에 영향이 끼치지 않습니다.

설계를 잘하기 위해서는 우리는 두가지 노력을 해야합니다.

  1. 암묵적 입력과 출력을 최소화
  2. 엉켜있는 코드를 풀어서 설계하기

암묵적인 입력과 출력을 최소화

명시적인 인자로 바꿔줍시다.

엉킨 코드 풀기

이 함수는 배열에 새로운 요소를 넣는 간단한 동작을 하는 것처럼 보입니다.

function addItem(cart, name, price){
  var newCart = cart.slice();
  newCart.push({
    name: name,
    price: price
  });
  return newCart;
}

그러나 자세히 살펴보면 많은 역할을 하고 있습니다.

function addItem(cart, name, price){
  var newCart = cart.slice(); // 배열 복사하기
  newCart.push({ // item 객체 만들기, item 객체 추가하기
    name: name,
    price: price
  });
  return newCart; // 복사본 리턴하기
}

그 중 item를 다루는 코드를 분리해봅시다.

function addItem(cart, item){
  var newCart = cart.slice();
  newCart.push(item);
  return newCart;
}

function makeCartItem(name, price){
  return{
    name: name,
    price: price
  };
}

addItem(shoppingCart, makeCartItem('apple', 3000))

cart와 item의 관심사를 분리하면 확장에 용이합니다.
만약, item의 객체에 discount 필드가 추가된다면 다른 함수를 수정하지 않고 makeCartItem의 인자에 discount를 추가하기만 하면 될 것입니다.