반디북
쏙쏙 들어오는 함수형 코딩
Ch7
우석

신뢰할 수 없는 코드를 쓰면서 불변성 지키기

방어적 복사

  • 내부 동작을 알 수 없는 library의 메서드를 사용한다면 카피-온-라이트를 적용할 수 없다.
  • 이런 상황에서는 방어적 복사를 통해서 불변성을 지킬 수 있다.

function add_item_to_cart(name, price) {
  ...
 
  black_friday_promotion(cart);
  ...
}
 
/* 방어적 복사 적용 */
function add_item_to_cart(name, price) {
  ...
 
  black_friday_promotion_safe(cart);
  ...
}
 
function black_friday_promotion_safe(cart) {
  var cart_copy = deepCopy(cart);
  black_friday_promotion(cart_copy);
  return deepCopy(cart_copy);
}
  • add_item_to_cart()에서 black_friday_promotion()를 알 수 없는 코드라 가정하자.
  • black_friday_promotion_safe()처럼 신뢰할 수 없는 코드를 래핑해서 사용하면 불변성을 보장할 수 있다.
  • 방어적 복사는 아래 2가지 로직을 통해 적용 가능하다.
    • 데이터가 안전한 코드에서 나갈 때 복사하기
    • 안전한 코드로 데이터가 들어올 때 복사하기
  • 단, 방어적 복사에서 복사는 깊은 복사여야 한다. (어떤 데이터가 변경되는지 모르기 때문)

Javascript에서 깊은 복사 구현하기

  • Javascript에서 객체의 깊은 복사를 수행하기는 어렵다,
  • 깊은 복사를 위해서는 객체의 복사를 재귀적으로 수행해야 한다.
  • 때문에 미리 만들어진 Lodash 라이브러리를 활용하자
만혁

신뢰할 수 없는 코드를 쓰면서 불변성 지키기

우리가 만든 카피-온-라이트 코드는 신뢰할 수 없는 코드와 상호작용 해야한다.

방어적 복사는 원본이 바뀌는 것을 막아 준다.

방어적 복사 규칙

  1. 데이터가 안전한 코드에서 나갈 때 복사하기
    • 불변성 데이터를 위해 깊은 복사본을 만든다.
    • 신뢰할 수 없는 코드로 복사본을 전달한다.
  2. 안전한 코드로 데이터가 들어올 때 복사하기
    • 변경될 수도 있는 데이터가 들어오면 바로 깊은 복사본을 만들어 안전한 코드로 전달
    • 복사본을 안전한 코드에서 사용
연습 문제

payrollCacl() 함수에 방어적 복사를 적용해라

function payrollCacl(emplyoees) {
    // ...
    return payrollChecks;
}
 
 
function payrollCaclSafe(emplyoees) {
    const copy = deepCopy(emplyoees);
    const payrollChecks = payrollCacl(copy);
    return deepCopy(payrollChecks);
}

리팩토링

userChanges.subscribe(function(user) {
    const copy = deepCopy(user);
    processUser(copy); // 안전 지대 함수
})

깊은 복사는 얕은 복사보다 비싸다