Search
1️⃣

Pattern 1. 데이터 / 계산 / 액션 → 순수 함수로 분리하기

1. "이 함수, 믿을 수 있나?"

“이 함수에 너무 많은 것들이 엮여 있어서 읽거나 건드리기 힘들어요.”
"이 함수는 왜 어떨 땐 잘 되는데, 어떨 땐 이상하게 동작하죠?"
"이 함수는 테스트하기 너무 어려워요."
이런 고민을 해본 적이 있다면, 당신은 이미 이 패턴이 필요한 이유를 몸으로 느끼고 있는 것입니다. 이런 '예측 불가능성'의 근원은 대부분 역할이 다른 코드들이 한곳에 뒤섞여 있기 때문입니다.
우리의 뇌는 '순수한 논리'를 이해하는 부분과 '외부 세계의 불확실성'에 대응하는 부분이 다르게 작동합니다.
이 두 가지 종류의 코드가 한 함수 안에 섞여 있으면, 우리는 두 가지 모자를 동시에 쓰려 애쓰는 것처럼 인지 과부하에 빠집니다. 이는 단일 책임 원칙(SRP) 원칙의 명백한 위반입니다.
이 패턴의 목표는 명확합니다. 내 코드에 '믿을 수 있는 영역''의심 / 조심해야 하는 영역' 사이에 명확한 경계선을 긋는 것입니다.

2. 코드를 나누는 세 가지 기준: 데이터, 계산, 액션

우리의 전략은 간단합니다. 신뢰할 수 있는 '계산'의 영역을 최대한 넓히고, 예측 불가능한 '액션'의 영역을 최대한 작고 고립된 경계 밖으로 몰아내는 것입니다.
함수형 프로그래밍에서 가져온 이 원칙은 모든 코드를 세 가지 역할로 명확히 구분합니다.
데이터 (Data)
계산 (Calculation)
액션 (Action)
분류 연습

3. Trigger: 뒤섞인 코드를 보고 '신호' 감지하기

언제 이 패턴을 떠올려야 할까요? 아래와 같은 '신호(Trigger)'를 발견했을 때입니다.
"API 호출 부분만 빼고 재사용하고 싶은데..."
"이 함수는 왜 실행할 때마다 결과가 미묘하게 다르지?"
"이 함수, 테스트하려면 Mock이 몇 개나 필요하지?"
아래 함수는 주문을 처리하는 간단한 코드처럼 보이지만, '계산'과 '액션'이 위험하게 뒤섞여 있습니다. 이런 코드를 보면 "분리하자!"는 신호를 느껴야 합니다.
function processOrder(items) { console.log('Processing order...') // 💥 액션 const total = items.reduce( // 계산 (sum, item) => sum + item.price * item.quantity, 0 ); if (total > 100) { localStorage.setItem('vip', 'true'); // 💥 액션 } const tax = total * 0.1; // 계산 fetch('/api/order', { // 💥 액션 method: 'POST', body: JSON.stringify({ items, total, tax }) }); return total + tax; // 계산 }
TypeScript
복사

4. Ability: 역할에 따라 코드 분리하기

이제 실제로 코드를 분리하며 어떤 일이 일어나는지 보겠습니다.
 Case 1: 간단한 가격 계산
 Case 2: 복잡한 비즈니스 로직
 Case 3: React 컴포넌트에서 분리
핵심: 코드를 쓸 때마다 스스로에게 질문하세요. "이것은 데이터인가? 계산인가? 액션인가?"
그리고 가능한 한 많은 로직을 '계산'의 영역으로 옮기세요. 그러면 당신의 코드는 놀랍도록 단순하고, 견고하며, 신뢰할 수 있게 될 것입니다.