더 좋은 액션 만들기
- 5.1 비즈니스 요구사항과 설계
- 5.2 암묵적 입력과 출력 줄이기
- 5.3 설계는 엉켜있는 코드를 푸는 것
- 5.4 카피-온-라이트 맛보기
- 5.5 더 좋은 액션의 조건
좋은 설계란 뭔가를 추가하는 게 아니라 엉켜있는 것을 푸는 것이야.
MegaMart에 새로운 요구사항이 들어와 — "장바구니에 아이템을 추가할 때, 합계가 20달러 이상이면 무료 배송 아이콘을 표시하라." 이걸 구현하려면 각 아이템 옆에 "이걸 추가하면 무료 배송이 되는지"를 미리 계산해야 하거든. 기존 코드에 이 기능을 추가하면서 설계 문제가 드러나. 처음 구현은 전역 장바구니를 직접 수정하면서 합계를 계산하고, DOM을 바꾸는 큰 함수 하나에 전부 들어있어. 함수가 너무 많은 일을 하고, 재사용이 안 되고, DOM 없이는 테스트도 불가능하지.
4장에서 배운 원칙을 다시 적용하는데, 이번에는 한 단계 더 깊이 — 함수 하나에서 암묵적 입출력을 빼내는 게 아니라, 함수를 여러 개로 쪼개면서 각각의 암묵적 입출력을 줄여. 핵심은 하나의 함수가 하나의 일만 하게 만드는 거야. 장바구니에 아이템 추가하는 함수(계산으로 분리 가능), 합계 계산하는 함수(계산), 무료 배송 여부 판단하는 함수(계산), DOM을 업데이트하는 함수(액션이지만 최소한의 일만)로 쪼개면, "무료 배송 여부 판단"은 function gets_free_shipping(cart) 같은 순수한 계산으로 분리되고 어디서든 재사용할 수 있게 돼.
저자가 여기서 설계에 대한 관점 하나를 제시하는데, 코드가 엉켜있다는 건 한 함수가 여러 가지 일을 하거나, 한 가지 일을 바꾸려면 관련 없는 다른 것도 바꿔야 하거나, 일부만 테스트할 수 없고 전체를 돌려야 하는 상태를 말해. 이걸 푸는 방법은 재사용하기 쉽게 — 함수가 하나의 일만 하면 다른 곳에서도 쓸 수 있고, 유지보수하기 쉽게 — 한 가지를 바꿀 때 한 곳만 수정하면 되고, 테스트하기 쉽게 — 작은 단위로 독립적으로 테스트 가능하게 만드는 거야. 이 원칙은 함수형 프로그래밍만의 것이 아니라 소프트웨어 설계 전반의 원칙인데, 액션/계산/데이터 분류가 "어디가 엉켜있는지"를 찾는 좋은 렌즈가 되지.
그리고 여기서 **카피-온-라이트(copy-on-write)**가 맛보기로 등장해. 장바구니에 아이템을 추가하는 기존 코드를 보면:
function add_item_to_cart(cart, item) {
cart.push(item); // 원본 배열을 직접 수정!
return cart;
}
이건 암묵적 출력이야. 인자로 받은 cart를 직접 수정하니까. 호출하는 쪽에서 "이 함수가 내 cart를 바꿀 줄" 몰랐을 수 있거든. 카피-온-라이트 방식으로 바꾸면:
function add_item_to_cart(cart, item) {
var new_cart = cart.slice(); // 복사본 만들기
new_cart.push(item); // 복사본 수정
return new_cart; // 복사본 리턴
}
원본을 건드리지 않고 복사본을 만들어서 수정하고 리턴해. 이러면 이 함수는 계산이 돼. 입력(cart, item)이 같으면 출력(new_cart)이 항상 같고, 원본을 바꾸지 않으니 부수효과도 없어. 이 패턴은 6장에서 본격적으로 다루게 돼.
액션을 완전히 없앨 수는 없잖아. 사용자 클릭 처리, DOM 업데이트, API 호출 — 이건 어쩔 수 없이 액션이야. 그러면 "더 좋은 액션"이란 뭘까? 저자의 기준은 작은 액션(최소한의 일만 하는 액션, 계산을 최대한 빼내고 남은 껍데기), 명확한 액션(이 함수가 어떤 부수효과를 일으키는지 시그니처만 보고 알 수 있는 액션), 격리된 액션(다른 액션에 영향을 주지 않고, 다른 액션의 영향을 받지 않는 액션)이야. 결국 계산을 최대한 빼내고, 남은 액션은 최대한 얇게라는 원칙의 반복이지.
정리
5장 읽고 기억할 거 세 가지:
- 설계 = 엉켜있는 코드를 푸는 것. 한 함수가 여러 일을 하면 엉킨 거. 하나씩 분리
- 카피-온-라이트 = 복사하고 수정하고 리턴. 원본을 건드리지 않으면 계산이 됨
- 좋은 액션 = 작고 명확하고 격리된 액션. 액션의 크기를 최소화하는 게 목표