Skip to main content

Command Palette

Search for a command to run...

[React] 좋은 추상화란 무엇인가(2) 잘못된 추상화는 중복보다 비싸다

Updated
3 min readView as Markdown
D

프론트엔드 개발자 doit입니다.

지난 글을 보면 성급했던 재사용 컴포넌트 경험으로 고생을 한 적이 있었는데요.
(아직 안 보셨다면? [1편: 좋은 추상화란 무엇인가(1)?] )

애초에 왜 이런 고생을 했을까를 생각해 보면
이유는 단순했습니다. 중복 코드가 거슬리니 바로 추상화를 해버린 것이었죠..
똑같은 실수를 반복하지 않기 위해 저만의 기준이 필요하다고 느꼈습니다.

이에 대해 이미 깊이 고민하셨던 Cher Scarlett님과 Kent C. Dodds님의 글을 보면서, 제가 취해야 할 태도는 무엇이고 경계해야 할 것은 무엇인지 다시 한번 생각해 보게 되었습니다.

그래서 오늘은 "성급한 추상화(Hasty Abstraction)"의 위험성과, 이를 피하기 위한 AHA Programming에 대해 이야기하려 합니다.


개발자들이라면 흔히 겪는 일종의 "코드 중복 제거 강박"이죠..

저 역시 비슷한 코드가 보이면 참지 못하고 추상화를 시도하곤 했습니다. 하지만 그 끝에는 "잘못된 추상화의 늪"이 기다리는 경우가 종종 생기곤 합니다.

잘못된 추상화의 늪 (The Wrong Abstraction)

Sandi Metz는 그녀의 아티클 "The Wrong Abstraction"에서 개발자들이 어떻게 지옥에 빠지는지 묘사합니다.

  1. 프로그래머 A가 중복 코드를 발견합니다.

  2. 중복을 추출하여 함수로 만들고 이름을 붙입니다. (추상화 생성)

  3. 중복된 코드를 새로운 추상화로 대체합니다.

  4. "아, 코드가 완벽해졌다." 프로그래머 A는 행복하게 자리를 떠납니다.

  5. 시간이 흐르고, 현재 추상화와 거의 비슷하지만 아주 조금 다른 새로운 요구 사항이 등장합니다.

  6. 프로그래머 B가 이 업무를 맡습니다.

  7. 프로그래머 B는 기존 코드를 유지해야 한다는 압박감을 느끼고, 파라미터를 추가하여 조건부로 동작하게 만듭니다.

  8. 또 다른 요구사항, 또 다른 파라미터... 코드가 이해 불가능해질 때까지 이 과정이 무한 반복됩니다.

"Sandi Metz는 이 현상을 한 문장으로 요약합니다

"Duplication is far cheaper than the wrong abstraction."
(잘못된 추상화보다 중복 코드가 훨씬 저렴하다.)

잘못된 추상화를 억지로 유지보수하는 비용(이해하기 힘듦 + 수정하면 다른 곳 터짐)이, 차라리 코드를 복사해서 따로 관리하는 비용보다 훨씬 크다는 뜻입니다.


그렇다면 언제 추상화를 해야 할까요?

Kent C. Dodds는 다음과 같이 소개합니다.

1. DRY (Don't Repeat Yourself)

  • "모든 지식은 시스템 내에서 단 하나의 유일한 표현을 가져야 한다."

  • 이것은 일반적으로 좋은 관행이며 저도 대체로 동의합니다

  • 물론 좋은 원칙입니다. 버그를 한 곳에서만 고치면 되니까요.

  • 하지만 저는 중복을 없애는 데 집착하다가, 오히려 잘못된 추상화를 만들어 더 고통 받은적이 있습니다

2. WET (Write Everything Twice)

  • 어떤 개발자들은 이에 대한 반작용으로 "두 번은 써라"라고 말합니다.

  • "세 번째 반복될 때까지는 추상화하지 마라"는 뜻이죠.

  • 하지만 이것도 "3번"이라는 숫자에 집착하는 또 다른 강박이 될 수 있습니다.

3. AHA (Avoid Hasty Abstractions) 💡

  • Kent C. Dodds가 Cher Scarlett에게 영감을 받아 제안한 개념입니다.

  • "성급한 추상화를 피하라."

  • 이 원칙의 핵심은 "숫자(몇 번 반복했냐)가 중요한 게 아니라, 타이밍이 중요하다"는 것입니다.

우리는 미래를 알 수 없습니다. 오늘 완벽해 보이는 API도 내일 기획이 바뀌면 쓰레기가 될 수 있습니다.

섣불리 합치면(Coupling), 나중에 분리하기 위해 엄청난 비용을 치러야 합니다.

Kent C. Dodds는 이렇게 말합니다.

"The commonalities will scream at you."

(공통점이 당신에게 비명을 지를 때까지 기다리세요.)

코드를 복사-붙여넣기 하는 것을 두려워하지 마세요.

여러 곳에서 코드가 쓰이면서 "확실한 패턴"이 보이고, "이건 무조건 합쳐야 해!"라는 확신이 들 때, 그때 추상화해도 절대 늦지 않습니다.


마치며

이제는 중복 코드가 보인다고 해서 무작정 추상화하지 않으려 합니다. 대신 합치기 전에 한 번 더 생각하려 합니다.

"지금 합치면 나중에 기획이 바뀌었을 때 쉽게 수정할 수 있을까?"

"합쳤을 때의 이점(Benefit)이 유지보수 비용(Cost)보다 정말로 큰가?"

결국 좋은 추상화란 단순히 코드를 짧게 만드는 기술이 아니라, 변화에 유연하게 대처하는 지속 가능한 코드를 만드는 것임을 배웠기 때문입니다.

Reference

25 views

More from this blog

Agent Skill로 README 자동화하기

저는 요즘 업무에서 AI 에이전트를 적극적으로 활용하여 반복적인 업무를 최대한 AI로 자동화하기 위해 공부 중인데요. 이번에 했던 작업 중 하나가 README 파일 생성 자동화입니다. AI에게 README를 써달라고 하면 꽤 그럴싸한 결과물이 나옵니다. 하지만 여러 프로젝트에 반복하다 보면 프롬프트가 모호할 때마다 매번 다른 방식으로 문제를 풀기 때문에 들

Mar 31, 20268 min read8

배열을 처리하는 세 가지 방법 (chaining, reduce, for loop)

개발을 하다 보면 배열 데이터를 가공할 일이 정말 많은데요.저는 평소에는 filter, map 같은 메서드 체이닝 방식을 주로 사용합니다. 읽기 쉽고, 데이터 흐름이 단계별로 명확하게 보이기 때문이죠. 하지만 어떠한 계기로(?) 인해 이런 의문을 가지게 되었습니다.. "만약 데이터가 수천만 건으로 늘어난다면? 배열을 여러 번 순회하는 체이닝 방식이 성능 병목을 일으키지는 않을까?" 혹은 "reduce 하나로 합치는 게 베스트일까?" 이 질문을 ...

Feb 4, 20263 min read19

[React] 좋은 추상화란 무엇인가(1) ? 유연한 컴포넌트 설계를 위한 제어의 역전

재사용을 위해 만든 컴포넌트가, 시간이 지날수록 오히려 재사용하기 어려워진 경험이 있으신가요? 저는 최근 프로젝트에서 SearchFilter 컴포넌트가 그러한데요 프로젝트에는 여러 목록 페이지가 존재했고, 페이지마다 검색 조건이 제각각이었습니다. 그래서 처음에는 Configuration 배열만 넘기면 알아서 그려주는 컴포넌트를 만들었습니다. // ❌ 초기의 설정 기반 접근 (Configuration) const filterFields = [ ...

Dec 9, 202510 min read36

React 시대의 함수형 프로그래밍

바닐라 JS처럼 개발자가 DOM과 상태 변경을 직접 제어하던 시기에는 불변성·순수 함수 같은 함수형 프로그래밍 철학이 지금처럼 중요하지는 않았습니다. 하지만 React(Vue/Redux/SWR/Recoil 등)처럼 선언적·상태 기반 UI가 등장하면서 상태를 “데이터 흐름의 스냅샷”으로 다뤄야 했고, 그때부터 함수형 프로그래밍이 중요해지기 시작했습니다. 🔥 바닐라 JS에서는 왜 FP가 별로 중요하지 않았을까? 바닐라 JS 시대의 UI 개발은...

Dec 8, 20255 min read35
D

Dlog!

39 posts

배우고, 나누며, 함께 성장하는 개발자 🚀