직교적 기능 설계의 대가들: 소수의 기능으로 무한한 가능성을 만드는 법
오리지널 위키를 넘어, 소프트웨어 역사상 가장 성공한 제품들은 "적을수록 많다"는 역설을 증명해왔다. 이들은 3~10개의 직교적 기능을 조합해 수천 가지 사용 사례를 해결하며, 기능 효율성(달성 요구사항 수 / 기능 수)에서 압도적 우위를 보인다.
본 연구는 Vim, Git, SQLite, Redis, Unix 도구, 스프레드시트 등 7개 핵심 사례와 그 설계자들의 사고 프로세스를 분석하고, iTunes와 Evernote 같은 실패 사례와 대조하며, 이러한 설계 역량을 키우는 구체적 방법을 제시한다. 핵심 통찰: 직교적 설계는 우연이 아니라 의도적 훈련과 끊임없는 거절의 결과다.
직교적 설계의 실체: 곱셈의 힘
Vim: 25개 기본 요소로 수천 개 명령을 만드는 모달 편집의 교과서
Vim의 천재성은 연산자(operator) × 동작(motion) × 텍스트 객체 = 조합 폭발이라는 문법에 있다.
d(delete), c(change), y(yank) 같은 10개 핵심 연산자와 w(word), $(end of line), }(paragraph) 같은 15개 동작을 학습하면, 자동으로 O(c × m) = 150가지 조합을 얻는다.
dw(단어 삭제), c$(줄 끝까지 변경), 3dd(3줄 삭제)처럼 즉석에서 새 명령을 '발명'할 수 있다.
![Why Vim Is More than Just an Editor – Vim Language, Motions, and Modes Explained Why Vim Is More than Just an Editor – Vim Language, Motions, and Modes Explained]()
더 강력한 것은 확장성이다. 한 개발자가 새 연산자를 만들고, 다른 개발자가 새 동작을 추가하면, 이 둘은 서로를 알지 못해도 완벽히 조합된다.
"무엇을 할지"(연산자)와 "어디서 할지"(동작)의 완전한 분리가 이를 가능케 한다.
Bill Joy는 이를 "300 baud 모뎀에 최적화"하기 위해 설계했다고 회고한다 - 네트워크가 느려 화면 갱신보다 사고가 빠를 때도 생산적으로 편집할 수 있도록.
비용: 가파른 학습 곡선. 모달 편집은 대부분 사용자에게 낯설다.
하지만 학습 후 생산성은 기하급수적으로 증가한다.
Unix 도구와 파이프: 정원 호스처럼 연결되는 프로그램들
Doug McIlroy가 1964년 "프로그램을 정원 호스처럼 나사로 조립하자"고 제안한 후, 9년이 걸려 1973년 Ken Thompson이 마침내 파이프를 구현했다.
"다음 날 아침, 우리는 원라이너 잔치를 벌였다. 모두가 자기 원라이너를 보여줬다. 이걸 봐, 저것 좀 봐... 그때 모두가 Unix 철학을 내놓기 시작했다. 한 가지를 잘 하는 프로그램을 작성하라. 함께 작동하는 프로그램을 작성하라. 텍스트 스트림을 다루는 프로그램을 작성하라, 그것이 범용 인터페이스다." ![John D. Cook John D. Cook]()
핵심은 세 가지 직교적 개념이다:
- 프로세스: 한 가지를 잘 하는 프로그램
- 텍스트 스트림: 표준 입력/출력/에러로 통일된 인터페이스
- 파이프(
|): 출력을 입력으로 연결하는 조합 연산자
cat access.log | grep "ERROR" | wc -l 같은 명령은 세 개의 단순한 도구를 조합해 "로그에서 에러 줄 수 세기"라는 새 기능을 즉석에서 만든다. 각 도구는 독립적으로 유용하지만, 조합될 때 진정한 힘이 발현된다.
![How the 9 major tenets of the Linux philosophy affect you | Opensource.com How the 9 major tenets of the Linux philosophy affect you | Opensource.com]()
McIlroy의 회고: "우리는 Unix 방에 앉아서 '뭘 제거할 수 있을까? 왜 이 옵션이 있지?'라고 물었다. 옵션이 필요한 건 대부분 기본 설계가 제대로 안 된 것이다 - 올바른 설계점을 찾지 못한 것이다. 옵션을 추가하는 대신, 왜 그 옵션을 추가하게 만들었는지 생각하라."
Git: 4개 객체 타입으로 분산 버전 관리 구축
Linus Torvalds는 2005년 BitKeeper 라이선스 분쟁 후 10일만에 Git 첫 버전을 작성했다. 하지만 그 전 4개월(2004년 12월~2005년 4월)을 코드 없이 설계를 고민하는 데 썼다.
"파일 시스템 관점에서 접근했다"
- 버전 관리를 내용 주소 지정 파일 시스템으로 취급한 것이 핵심 통찰이다.
4개 객체 타입만으로 모든 것을 구축한다:
- Blob: 파일 내용만 (메타데이터 없음)
- Tree: 디렉토리 구조 (blob과 다른 tree 참조)
- Commit: tree를 역사로 연결 (작성자, 메시지, 부모 포함)
- Tag: 커밋에 대한 명명된 포인터
![GitHub GitHub]()
이 4개 프리미티브로 버저닝, 브랜칭, 병합, 분산 워크플로우, 히스토리 관리를 모두 처리한다. SHA-1 해시로 내용을 식별하므로 손상 감지가 자동이다.
Plumbing(저수준 명령)과 Porcelain(고수준 명령)을 분리해, 스크립트 작성과 도구 제작이 핵심 추상화를 건드리지 않고 가능하다.
![The Architecture of Open Source Applications (Volume 2)Git The Architecture of Open Source Applications (Volume 2)Git]()
Torvalds: "두세 개의 근본적인 설계 아이디어를 갖는 것... 저수준 설계가 몇 가지 핵심 개념을 가지면 더 쉬워진다."
![Git turns 20: A Q&A with Linus Torvalds Git turns 20: A Q&A with Linus Torvalds]()
Lua: 3개 메커니즘으로 완전한 프로그래밍 언어
Lua의 모토는 "정책이 아닌 메커니즘"이다.
25,000줄의 C 코드, 200KB 바이너리에 완전한 언어를 담았다.
비결은 세 가지 범용 메커니즘이다:
- 테이블: 배열, 레코드, 모듈, 객체, 클래스 - 모든 자료구조를 위한 단 하나의 메커니즘
- 함수: 일급 함수와 렉시컬 스코핑으로 모든 추상화 처리
- 코루틴: 비대칭 코루틴으로 모든 제어 흐름 처리
![A Look at the Design of Lua – Communications of the ACM A Look at the Design of Lua – Communications of the ACM]()
{x=10, y=20} 같은 테이블은 레코드로, {10, 20, 30}은 배열로, 메타테이블(__index)을 추가하면 프로토타입 기반 객체 시스템으로 작동한다. 하나의 메커니즘, 여러 정책. 설계자들: "우리는 많은 다른 기능을 추가하는 대신, 프로그래머가 그런 기능을 직접 구현할 수 있는 소수의 메커니즘만 만들었다."
![A Look at the Design of Lua – Communications of the ACM A Look at the Design of Lua – Communications of the ACM]()
레퍼런스 매뉴얼이 100페이지에 불과하다 (언어, 라이브러리, C API 모두 포함). ![A Look at the Design of Lua A Look at the Design of Lua]()
스프레드시트: 2개 프리미티브로 조 달러 산업 창출
VisiCalc(1979)와 Excel의 핵심은 그리드 + 수식 두 개념뿐이다:
- 그리드: A1, B2 같은 셀의 행과 열
- 수식: 다른 셀을 참조하는 표현식 (
=A1+B1) ![VisiCalc: Revolutionary Impact in Personal Computing VisiCalc: Revolutionary Impact in Personal Computing]()
이 둘로 예산 추적, 재무 모델링, "만약에"(what-if) 분석, 차트, 피벗 테이블이 모두 가능하다. 수식이 수식을 참조하면 복잡한 의존성 체인이 생성되고, 한 셀만 바꾸면 전체가 재계산된다.
"프로그래밍을 모르는 사람을 위한 프로그래밍" - 친숙한 종이 장부 은유로 복잡한 계산을 접근 가능하게 만들었다. ![VisiCalc - Wikipedia VisiCalc - Wikipedia]()
40년 후에도 근본 설계는 불변이다.
VisiCalc은 6년간 70만 카피 팔렸고, "하드웨어를 끌고 다니는 소프트웨어 꼬리"가 될 수 있다는 평가를 받았다.
![VisiCalc - Wikipedia VisiCalc - Wikipedia]()
직교적 설계의 탄생 과정: 단순화는 전쟁이다
Rich Hickey의 "Simple Made Easy": 복잡함과 쉬움의 구별
Hickey는 단순함(simple)과 쉬움(easy)을 혼동하지 말라고 강조한다:
- Simple: 하나로 접혀있음, 객관적, 산출물에 관한 것. 반대는 complex(얽혀있음)
- Easy: 손에 가까이 있음, 익숙함, 주관적. 반대는 hard(어려움)
![infoq infoq]()
"우리는 몇 개 공만 저글링할 수 있다" - 인간 인지 한계 때문에 단순함이 필수다. 단순함은 선택이고, 우리에겐 복잡함의 문화가 있다.
쉬움을 선택하면 초반엔 빠르지만 누적된 복잡도가 프로젝트를 죽인다. 단순함을 선택하면 초반엔 느리다(생각해야 하니까).
![talk-transcripts/Hickey_Rich/SimpleMadeEasy.md at master · matthiasn/talk-transcripts talk-transcripts/Hickey_Rich/SimpleMadeEasy.md at master · matthiasn/talk-transcripts]()
Hickey의 설계 프로세스:
- What (무엇): 인터페이스, 프로토콜로 함수 집합 정의. 구현은 나중에
- Who (누가): 데이터/엔티티 정의. 하위 컴포넌트를 인자로 전달, 하드코딩 금지. 더 많은 컴포넌트로 구축하라, 더 적은 게 아니라
- How (어떻게): 구현 세부사항은 마지막. 앞서 정의한 다형성 사용. 다른 것과 얽히지 않도록 격리
- When/Where (언제/어디서): 큐를 사용해 객체를 직접 연결하지 않음. 시간적으로 얽히지 않게
핵심: "Complect는 끼워넣다, 얽히다, 엮다를 뜻한다. Compose는 함께 놓다를 뜻한다. 모듈 컴포넌트를 조합하는 것은, 모듈들이 고도로 상호연결되어 있다면 단순하지 않다." ![8 Things I Learned from Rich Hickey That Helped Me Write Better Software (Simple Made Easy) 8 Things I Learned from Rich Hickey That Helped Me Write Better Software (Simple Made Easy)]()
DHH와 37signals: 빌드하며 사용하는 철학
37signals는 Basecamp를 한 번에 한 기능씩 만들었다.
"Basecamp가 어떤 가치라도 갖기 위해 반드시 해야 하는 한 가지는 무엇인가? 우리에겐 그게 Messages 섹션이었다... 그 공이 굴러가기 시작하면, 다음에 작업할 것이 거의 자명해진다." ![]()
핵심 프로세스:
- 만들면서 사용하기: "유용하게 작동하는 소프트웨어에 도달하는 유일한 방법은 빌드와 계획을 동시에 하는 것이다"
![]()
- 기능 명세 없이 UI 직행: "단락으로 써서 소프트웨어가 뭘 해야 할지 상상하는 대신, 우리는 바로 요소들로 간다"
![]()
- 소프트웨어를 사용하면 한두 개 기능이 다음으로 가장 중요한 것으로 계속 떠오른다
"아니요"라고 말하는 전략: "고객 설문에서 모두가 우리 제품에서 가장 좋아하는 건 단순함이라고 말한다. 그런데 같은 호흡으로 '아, 이 단순한 것들 다 좋아요. 그런데 A, B, C 추가해주세요'라고 한다. 만약 우리가 그들의 A, B, C와 다른 모든 사람들의 D, E, F를 추가한다면, 그들은 더 이상 소프트웨어를 좋아하지 않을 것이다. 더 이상 단순하지 않을 테니까."
![Episode 132: Simplicity by Design for Product Development with Jason Fried, Co-founder and CEO of 37signals — Produx Labs Episode 132: Simplicity by Design for Product Development with Jason Fried, Co-founder and CEO of 37signals — Produx Labs]()
환경설정에 대한 철학: "소프트웨어에 환경설정을 넣어야 할 때마다, 우리는 그걸 거의 패배로 여긴다. 우리가 대부분의 사람들이 대부분의 경우에 좋아할 합리적인 선택을 내리기에 충분히 훌륭하지 못했다는 것이다." ![]()
Doug McIlroy의 9년 집념: 파이프가 만들어지기까지
McIlroy는 1964년부터 1973년까지 9년간 Thompson과 Ritchie에게 파이프를 제안했다. 돌파구는 "파이핑과 함께 가는 셸 문법을 만들었을 때"였다. Thompson이 마침내 "하겠어. 이 얘기 듣는 것도 지쳤어"라고 했다.
![Doug McIlroy Doug McIlroy]()
다음 날 아침 "원라이너 잔치"가 벌어졌고, Unix 철학이 코드가 작동한 후 결정화되었다. Thompson은 "대부분의 프로그램을 표준 입력을 받도록 바꿔야 했다" - **사후 적응(retrofitting)**이 필요했다.
철학은 실천에서 나왔지, 사전 계획이 아니었다.
"기능 축소 싸움": "모든 것이 작았다... Linux의 크기를 보면 내 마음이 무너진다. 진짜 매뉴얼 페이지였던 것이 이제는 작은 책 한 권이고, 수천 개의 옵션이 있다... 우리는 Unix 방에 앉아서 '뭘 제거할 수 있을까? 왜 이 옵션이 있지?'라고 물었다. 옵션이 있는 이유는 대개 기본 설계에 결함이 있기 때문이다 - 올바른 설계점을 찾지 못한 것이다." ![Unix Philosophy | Encyclopedia MDPI Unix Philosophy | Encyclopedia MDPI]()
Richard Gabriel의 "Worse is Better": 50%로 시작해 바이러스처럼 퍼뜨려라
Gabriel은 1989년 "왜 C와 Unix가 Lisp보다 나은가?"라는 질문에 농담으로 "음, worse is better니까"라고 답했고, 이것이 진지한 설계 철학이 되었다. ![Wikipedia Wikipedia]()
뉴저지 접근법의 우선순위:
- 단순함 - 구현의 단순함이 인터페이스의 단순함보다 더 중요
- 정확성 - "단순한 것이 정확한 것보다 약간 낫다"
- 일관성 - 단순함을 위해 희생 가능
- 완전성 - 다른 품질을 위해 희생 가능. 구현 단순함이 위태로워질 때마다 완전성을 희생해야 한다
![Wikipedia Wikipedia]()
왜 작동하는가? "Worse-is-better 철학은 구현 단순함이 최우선이므로 Unix와 C는 이식하기 쉽다... 50% 기능의 Unix와 C가 만족스럽다면, 어디서나 나타나기 시작할 것이다... 바이러스가 퍼진 후엔 90%까지 개선하라는 압력이 생기지만, 사용자는 이미 올바른 것보다 못한 것을 받아들이도록 조건화되었다." ![dreamsongs dreamsongs]()
바이럴 전략: "올바른 것의 절반을 먼저 사용 가능하게 만들어 바이러스처럼 퍼뜨려라. 사람들이 중독되면, 시간을 들여 올바른 것의 90%까지 개선하라." ![Worse is better, also for organisational design | by Jason Yip | Medium Worse is better, also for organisational design | by Jason Yip | Medium]()
Ward Cunningham의 위키: 11개 설계 원칙
Ward는 2006년 WikiSym 강연에서 "위키의 초기 및 지속적 개발에 중요했던" 11개 원칙을 밝혔다:
- Open (열림): 누구나 편집 가능 (투과성)
- Incremental (점진적): 아직 작성되지 않은 페이지를 인용할 수 있어야 (불완전)
- Organic (유기적): 구조가 커뮤니티와 함께 성장하고 진화 (공진화)
- Mundane (평범함): 소수의 관례가 모든 필요한 서식 제공
- Universal (보편적): 메커니즘이 균일해야 (신뢰)
- Overt (명시적): 서식된 텍스트가 기본 마크업 성격을 암시해야
- Unified (통합됨): 페이지 이름이 플랫 공간에서 추출됨
- Precise (정확함): 유사한 주제의 페이지는 유사한 이름을 가져야
- Tolerant (관대함): 형식보다 해석 가능한(비록 거친) 텍스트가 더 중요
- Observable (관찰 가능): 활동이 명백하고 모니터링되어야
- Convergent (수렴함): 중복을 막거나 제거할 수 있어야
![Ward Cunningham on Design Principles – Blogschmog Ward Cunningham on Design Principles – Blogschmog]()
Ward의 철학: "나는 위키가 작다는 게 자랑스럽다. 하지만 그건 다른 모든 것(파일 시스템, cgi 스크립트, 웹 서버, 브라우저) 위에 세워진 것이다."
가장 짧은 위키 데모: 222자의 Perl 코드로 기본 위키 기능 구현. ![Ward Cunningham on Design Principles – Blogschmog Ward Cunningham on Design Principles – Blogschmog]()
Stripe의 PaymentIntents: 3개월 회의실 감금으로 재설계
Stripe는 2011년 출시 때 Charges API로 시작했다 - 미국 카드에는 단순했지만, 글로벌 결제 수단으로 확장하며 무너졌다. 문제: "카드만이 즉시 완료되고 고객 행동이 필요 없는 유일한 결제 수단이다." 가장 단순한 경우를 위해 추상화를 만들었고, 복잡도를 패치로 추가했다. "우리는 자동차에 부품을 추가해서 우주선을 만들려는 것 같았다."
2017-2018년, 5명 팀(엔지니어 4명, PM 1명)이 3개월간 회의실에 감금되어 재설계했다:
- 모든 결제 수단 검토
- 기존 추상화 무시
- "첫 원리부터 문제를 생각했다"
해결책: PaymentIntent + PaymentMethod 분리
- PaymentMethod: 어떻게 청구할지 (카드, 은행, Alipay 등) - 정적 정보
- PaymentIntent: 무엇을 청구할지 (금액, 통화) - 거래 상태 기계
- 관심사 분리: 결제 수단이 결제 흐름과 직교
이는 하위 호환성을 깨는 결정이었지만, 장기적으로 Stripe를 글로벌 결제 인프라로 만들었다. 2년 이상 생태계 마이그레이션이 필요했다.
실패 사례: 직교성을 잃은 제품들
Evernote: 기능 축적의 포스터 차일드
Evernote는 2008년 단순한 노트 앱으로 시작해 2014년 1억 사용자를 기록했다.
그리고 무너졌다. ![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
정량적 증거:
- 5,000개 이상 노트를 가진 사용자 계정이 2014년까지 사용 불가능해짐
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
- 5년 된 MacBook Pro에서 "실행 불가능"
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
- 각 iPhone 출시마다 앱이 느려져 최신 하드웨어 필요
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
기능 축적 증상:
- 리치 텍스트 편집, 파일 첨부, 노트북 스택 추가
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
- Post-It 노트 스캔, iPad 앱, IFTTT 레시피 통합
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
- Evernote Hello 출시 (나중에 LinkedIn 파트너십으로 교체)
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
- Evernote Food (사용자에게 목적 불분명)
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
- 알림 기능 (사용자: "쓰레기 버리려고 노트를 만드는 건 바보같다")
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
- 이메일 아카이빙 (Gmail이 이미 하는데?)
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
- 사진 정리 (Dropbox/OneDrive/Flickr가 우월)
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
미션 크립 소프트웨어를 넘어서:
- Evernote Moleskine 노트 판매
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
- $242짜리 노트북 가방 출시
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
- "모든 종류의 비싼 평범한 의류" 제공
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
- 프리미엄 구독: $5/월 vs $242 가방 - 가격 괴리
![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
사용자 불만: "기능 크립이 UI를 쓰기 더 어렵게 만든다", "모든 새 기능이 더 혼잡하게 만든다", "기능이 많을수록 느려진다", "원래 대체하려던 것들의 느린 버전이 되었다" ![Why I Stopped Using Evernote Why I Stopped Using Evernote]()
Pendo 연구: 평균 소프트웨어 기능의 80%는 거의 또는 전혀 사용되지 않는다
- Evernote에 직접 적용됨. ![Feature Creep Is Killing Your Software: Here’s How to Stop It Feature Creep Is Killing Your Software: Here’s How to Stop It]()
iTunes: "세계 최고 주크박스"에서 혼란스러운 괴물로
2001년 출시 때 Steve Jobs: 다른 음악 앱들은 "너무 복잡하다. 배우고 사용하기가 정말 어렵다". iTunes는 "세계 최고이자 가장 사용하기 쉬운 주크박스 소프트웨어"였다. ![iTunes: A look at Apple’s media app and its influence on an industry iTunes: A look at Apple’s media app and its influence on an industry]()
진화 타임라인:
- 2001: 출시 - 음악 재생만
![Apple launches iTunes, revolutionizing how people consume music | January 9, 2001 | HISTORY Apple launches iTunes, revolutionizing how people consume music | January 9, 2001 | HISTORY]()
- 2003: iTunes Music Store (20만 곡)
![History of iTunes - Wikipedia History of iTunes - Wikipedia]()
- 2004: 팟캐스트, 사진, 비디오 추가
![History of iTunes - Wikipedia History of iTunes - Wikipedia]()
- 2007: Cover Flow, 끊김 없는 재생
- 2008: App Store (대규모 복잡도 증가)
- 2010: Ping 소셜 네트워크 (실패, 빠르게 교체)
![iTunes: A look at Apple’s media app and its influence on an industry iTunes: A look at Apple’s media app and its influence on an industry]()
- 2012: 버전 12 - 복잡도 정점
- 2019: macOS에서 중단, Music, Podcasts, TV 앱으로 분리
![iTunes - Wikipedia iTunes - Wikipedia]()
사용자 불만: "iTunes는 한때 빠르고 단순했다... 앨범 커버 디스플레이로 더 화려하게 만들기로 결정한 이후... 훨씬 사용하기 어려워졌다. 현재 버전이 최악이다", "Windows Vista 운영체제만큼 부풀려진 실패"
아이러니: Jobs가 2001년 다른 앱들을 "너무 복잡하다"고 비판했는데, 2019년까지 iTunes 자체가 Jobs가 비판했던 모든 것을 구현했다. MacWorld: "iTunes는 유기적이지 않고 함께 묶인 것처럼 느껴지는 기능들의 혼란스러운 융합물이 되고 있었다."
Windows 8 Metro: 과도한 단순화의 재앙
2012년 출시, 2013년 중단/대폭 수정, 2015년 Windows 10에서 완전히 폐기.
Nielsen Norman Group 연구 (12명의 숙련된 PC 사용자 테스트):
정보 밀도 재앙:
- 음악 앱이 와이드스크린 모니터에 앨범 타일 24개만 표시
- 가로 스크롤 필요, 빠르게 스크롤하면 수 초간 "회색 타일" 로딩
- 뉴스 앱: 일반 웹사이트의 9개 기사 + 3개 광고 대신 3개 기사만
- 정보 밀도 66% 감소
듀얼 데스크탑 인지 부하:
- InfoWorld 리뷰: "Windows 8은 실패다 - 사용자를 동시에 두 방향으로 끄는 어색한 짬뽕"
- Metro와 전통적 데스크탑 사이를 전환해야 함
- 다른 앱, 다른 설정, 다른 규칙을 가진 두 개의 분리된 운영체제
- Internet Explorer가 각 모드에서 완전히 다르게 작동
숨겨진 기능과 컨트롤:
- 보이는 시작 버튼 없음
- 주소 표시줄과 탐색 버튼이 "대부분 사라짐"
- 발견하려면 빈 공간을 오른쪽 클릭 필요
- Nielsen Norman: "버튼이 아니고, 인터페이스가 아니다"
터치 중심 설계가 데스크탑에서 실패:
- 터치스크린에 최적화 (큰 타겟 유용)
- 터치 없는 전통적 PC 사용자에게 강요됨
- MIT Technology Review: "터치 기반 사용자 인터페이스는 정보 소비와 재미를 위해 명백히 설계되었고, 심각한 작업을 위한 것이 아니다"
실패 통계: Windows 8은 모든 Windows 버전 중 최저 채택률. Microsoft는 1년 안에 Windows 8.1 출시를 강요받았고, Windows 10은 전통적 시작 메뉴를 복원했다. 교훈: 파워 유저에게 "너무 최소"이면서 캐주얼 사용자에게 혼란스러울 수 있다.
기능 상호작용 문제: N+1의 악몽
학계 정의: "두 기능의 통합이 한 기능 또는 두 기능 모두의 동작을 수정할 때" 발생한다.
전화 통신 고전 예시:
- 고객이 착신 전환과 통화 대기를 모두 활성화
- 첫 통화: 전화 벨 울림, 정상 응답 - 문제 없음
- 두 번째 통화 도착:
- 보조 번호로 전환해야 하나? (착신 전환)
- 현재 통화자에게 알려야 하나? (통화 대기)
- 명백히 정확한 답 없음 - 기능이 예상치 못하게 상호작용
N+1 문제: N개 기능으로 N(N-1)/2 상호작용 가능
- 10개 기능 = 45개 상호작용
- 20개 기능 = 190개 상호작용
- 복잡도 폭발: 조합적 증가
직교적 설계 역량 키우기: 실천 가능한 방법론
코드 카타: 해법이 아닌 연습에 집중
Dave Thomas의 codekata.com: 30-60분 프로그래밍 연습, "목표는 연습이지 해법이 아니다"
단순함을 위한 주목할 카타:
- Kata 1 - 슈퍼마켓 가격: 다양한 가격 모델과 복잡도 탐색
- Kata 4 - 데이터 먼징: 유사한 루틴에서 공통성 추출
- Kata 9 - 체크아웃: 최소 복잡도로 가격 체계 처리
연습 방법:
- 같은 카타를 다른 접근법으로 여러 번 반복
- 각 반복마다 작은 개선에 집중
- 해법을 버리고 새로 시작
- 명확성과 단순함을 위해 접근법 비교
설계 카타: 화이트보드로 아키텍처 연습
Graham Lea의 프로세스:
- 설정: 점심 전 1시간 (정신 에너지 최고치), 화이트보드 있는 조용한 방
- 기능 선택: 도메인에서 실질적인 것 (≥1개월 빌드) 선택
- 독립 설계 단계 (20분): 각자 독립적으로 설계
- 공유 단계 (15분): 설계 발표, 아직 비판 없음
- 토론 단계 (20분): 접근법 비교, 패턴 식별
- 버리기: 구현하지 않음 - 순수 연습
이득: 설계 문제 패턴 인식 구축, 설계 결정 설명 연습, 대안 접근법 노출, 실험을 위한 낮은 위험 환경.
아키텍처 카타: 팀으로 시스템 설계
Ted Neward/Neal Ford: 소규모 그룹(3-5명)이 RFP 스타일 설명에서 시스템 설계
프로세스:
- 팀 구성: 다른 팀/배경 사람들 섞기
- 카타 선택: 무작위 또는 선택, 6주 규모 프로젝트
- 발견 단계: 진행자에게 요구사항 질문
- 설계 단계: 올바른 추상화 수준에서 해법 스케치
- 발표: 아키텍처 결정과 트레이드오프 설명
리소스: fundamentalsofsoftwarearchitecture.com/katas/, nealford.com/katas
Rich Hickey의 정신 모델: "얽힘"과 "조합"의 구별
핵심 통찰: "우리는 몇 개 공만 저글링할 수 있다"
단순함 달성 방법:
- 단순한 구조 선택: 객체보다 값, 메서드보다 함수, ORM보다 데이터
- "얽힘(complecting)" 피하기: 분리된 관심사를 엮지/끼워넣지 말라
- 코딩 전에 생각: "프로그래밍은 타이핑에 관한 게 아니라 생각에 관한 것이다"
- 산출물에 집중: 코드가 하는 것으로 판단, 작성 경험이 아니라
- "쉬운" 해법 의심: 상태는 쉽지만 모든 것을 복잡하게 만든다
단순 vs 복잡 선택:
- 단순: 값, 함수, 네임스페이스, 데이터, 다형성, 큐, 선언적 조작
- 복잡: 상태, 객체, 상속, ORM, 조건문, 명령형 루프
Casey Muratori의 압축 지향 프로그래밍
핵심 원칙: 최소 두 인스턴스가 있을 때까지 재사용 가능한 코드를 작성하지 말라
방법:
- 먼저 구체적 코드 작성: 즉각적 문제를 직접 해결
- 중복 기다리기: 패턴이 자연스럽게 나타나도록
- 명백할 때 압축: 진짜 반복을 볼 때 함수 추출
- 조기 추상화 피하기: 미래 요구 예측하지 말라
이점: "입자 불연속"(항상 하위 수준으로 내려갈 수 있음) 피함, 구체적에서 일반적으로 자연스러운 진행, 사용되지 않는 추상화에 낭비된 노력 적음
Shape Up 방법론: 제약이 단순함을 강요
3단계:
- 형성 (Shaping) (고위 리더십):
- 문제를 명확히 정의
- "식욕(appetite)" 설정 (기꺼이 쓸 시간)
- 올바른 추상화 수준에서 해법 스케치
- "토끼 구멍(rabbit holes)" 식별 (위험 영역)
- "노고(no-gos)" 정의 (명시적으로 범위 밖)
- 피치 작성
형성 도구:
- Breadboarding: 시각 설계 없이 흐름을 보여주는 단순 텍스트 표기법
- Fat marker 스케치: 의도적으로 거칠게 과도한 명세 피하기
- 베팅 (Betting) (2주 사이클): 피칭된 프로젝트 검토, 6주 사이클을 받을 것 선택, 백로그 없음
- 빌딩 (Building) (개발 팀): 팀이 식욕 내에서 범위 결정 소유, 6주 내에 배송 필수, 연장 없음, 시간이 아니라 범위를 자른다
단순함 학습 이점: 시간 제약을 통한 단순화 강요, "아니요"라고 말하도록 격려, 초기에 범위 명시적으로, 식욕 설정으로 범위 크립 방지.
진행 경로: 초보에서 고급까지
초보자 (1-6개월):
- "The Design of Everyday Things" 읽기
- "Simple Made Easy" 강연 시청
- 단순함에 집중하며 10개 이상 코드 카타 수행
- 주당 하나의 리팩토링 패턴 연습
- "이게 필요한가?" 질문 시작
중급자 (6-18개월):
- "Refactoring" 표지부터 끝까지 읽기
- Shape Up 방법론 연구
- 월별 설계 카타 수행
- 단순함에 집중한 코드 리뷰 리드
- 압축 지향 프로그래밍 연습
- 한 회사의 설계 철학 깊이 있게 연구 (37signals, Apple)
고급자 (18개월 이상):
- 분기별 아키텍처 카타
- 설계 결정에 대해 글쓰기 (블로그, 문서)
- 단순함 사고로 타인 멘토링
- 원칙을 사용해 처음부터 새 시스템 설계
- 전략 수준에서 설계 논의에 기여
- 개인 설계 철학 개발
교차 절단 패턴과 보편적 진실
7개 성공 사례의 공통 패턴
- 좌절에서 시작: 모든 제품이 기존 도구에 대한 창작자의 좌절에서 탄생
- Git: BitKeeper 라이선싱, CVS 느림
- SQLite: Informix 서버 불안정
- Redis: 실시간 요구를 위한 데이터베이스 성능
- Vim: 새 플랫폼에 vi 필요
- React: Facebook Ads 복잡도
- Stripe: 결제 통합 어려움
- 첫 원리부터 설계: 창작자들이 종종 자신의 도메인에서 형식적 훈련 부족, 신선한 접근으로 이어짐
- Hipp: 데이터베이스 교육 없음, 컴파일러 이론에서 발명
- Torvalds: 버전 관리에 파일 시스템 사고방식 적용
- Walke: UI에 함수형 프로그래밍 적용
- Sanfilippo: 데이터베이스 아마추어, 데이터 구조에 집중
- 직교성을 통한 단순함: 핵심 원칙 - 소수의 개념, 많은 조합
- Git: 4개 객체 타입 → 복잡한 버전 관리
- Vim: 연산자 × 동작 × 텍스트 객체 → 수천 개 명령
- SQLite: 하나의 파일, 하나의 프로세스 → 제로 구성
- Redis: 데이터 구조, 쿼리 아님 → 예측 가능한 성능
- React: 컴포넌트 + props + state → 복잡한 UI
- Stripe: PaymentIntent + PaymentMethod → 모든 결제 수단
- Unix 철학 영향: 명시적 또는 암묵적 준수
- 조합성: 예상치 못한 방식으로 부품이 결합
- 한 가지를 잘 하라: 단일 책임
- 텍스트 스트림 (Git, Unix 도구) 또는 명확한 인터페이스 (API)
- 직교성을 위한 트레이드오프: 공통 희생
- 더 가파른 학습 곡선: Git, Vim은 정신 모델 전환 필요
- 더 많은 초기 코드: React, Stripe는 처음에 더 많은 상용구 필요
- 성능 오버헤드: 때때로 (Redis 단일 스레드, Git 객체 모델)
- 마이그레이션 고통: Stripe의 2년 PaymentIntents 롤아웃
보편적 진실
- 단순함 ≠ 쉬움: 친숙함과 단순함을 혼동하지 말라
- 단순함은 힘든 작업: "무언가를 단순하게 만들려면 많은 힘든 작업이 필요하다"
- 인지 한계는 실제: 우리는 그렇게 많은 복잡도를 유지할 수 없다
- 복잡도가 죽인다: 모든 스프린트가 과거 작업 재수행에 관한 것이 된다
- 생각하라, 타이핑하지 말라: "프로그래밍은 타이핑에 관한 게 아니라 생각에 관한 것이다"
설계 휴리스틱
- 추가하기 전에 빼라: 먼저 기능 제거 시도
- 중복을 기다려라: 2개 이상 인스턴스가 있을 때까지 추상화하지 말라
- 만들지 않을 것을 정의하라: 제약이 설계를 명확히 한다
- 핵심에서 시작해 밖으로: 먼저 중심(epicenter) 찾기
- 가정을 의심하라: 특히 자신의 가정
불확실성 지도
가장 덜 자신있는 부분
- 인과관계 vs 상관관계: 연구는 직교적 설계를 가진 제품들이 성공했음을 보여주지만, 직교성이 성공의 원인인지 아니면 다른 요인(타이밍, 시장, 창작자의 명성)이 더 중요했는지 불명확. 예: Git은 Linus Torvalds의 명성 때문에 성공했을 수도.
- 생존자 편향: 직교적 설계를 시도했지만 실패한 제품들을 찾기 어려움. 성공한 사례만 문서화되고 기억됨. Google Wave가 한 예시지만 더 많은 실패 사례 필요.
- 도메인 의존성: 직교적 설계가 일부 도메인(개발자 도구, 프로그래밍 언어)에서는 잘 작동하지만 다른 도메인(소비자 앱, 엔터프라이즈 소프트웨어)에서는 덜 적용 가능할 수 있음. 연구가 개발자 중심 제품에 편향됨.
- 시대적 맥락: 1970년대-1990년대 제품들(Unix, Vim, Git)은 자원 제약이 단순함을 강요한 환경에서 탄생. 현대의 풍부한 리소스 환경에서 같은 원칙이 적용되는지 불확실.
지나치게 단순화했을 수 있는 부분
- 학습 곡선 비용 과소평가: Vim과 Git의 가파른 학습 곡선이 많은 잠재 사용자를 막았을 수 있음. 보고서는 "배운 후 생산성 증가"에 집중하지만, 대부분이 배우기 전에 포기하는 현실을 충분히 다루지 않음.
- 규모의 복잡도: 연구된 제품들 대부분이 소규모에서 시작. 대규모 조직/사용자 기반으로 확장할 때 직교성 유지가 훨씬 어려워짐. Evernote와 iTunes의 실패가 이를 시사하지만, 이것이 불가피한 것인지 관리 실패인지 불명확.
- 전문가 vs 일반 사용자: 직교적 설계가 전문가에게 최적화되었을 수 있음. Unix, Vim, Git은 개발자들에게 사랑받지만, 일반 소비자는 통합된 해법을 선호할 수 있음. Windows 8 실패가 이를 보여줌.
- 재무적 실현 가능성: 37signals처럼 작고 수익성 있는 회사로 남는 것이 모든 조직의 목표는 아님. 일부는 빠른 성장이 필요하고, 이는 기능 추가를 요구할 수 있음. "아니요"라고 말하는 전략이 모든 비즈니스 맥락에서 실행 가능한지 불확실.
의견을 바꿀 수 있는 질문/추가 정보
- 실패한 직교적 설계의 구체적 사례: "단순하고 직교적"으로 설계되었지만 시장에서 실패한 제품들. 이는 직교성이 충분조건이 아니라 필요조건임을 보여줄 것.
- 정량적 사용성 연구: Vim vs VSCode, Git CLI vs GitHub Desktop 같은 직교적 vs 통합적 도구의 통제된 사용성 테스트. 어느 그룹(초보, 중급, 전문가)에서 어느 접근법이 더 나은지.
- 기업 환경 사례 연구: 대기업(Google, Microsoft, Amazon)이 내부 도구에서 직교적 설계를 어떻게 적용하는지. 규모에서 유지 가능한지, 아니면 불가피하게 복잡도가 증가하는지.
- 비개발자 도메인: 의료 소프트웨어, 금융 도구, 교육 앱에서 직교적 설계의 성공/실패 사례. 개발자 도구 편향을 넘어선 일반화 가능성 테스트.
- 장기 유지보수 데이터: Vim(Bram Moolenaar 사후), Redis(Salvatore 퇴사 후) 같은 제품이 원래 창작자 없이 어떻게 진화하는지. 직교적 설계가 장기 유지보수를 실제로 쉽게 만드는지.
- 기능 제거의 정량적 영향: 제품이 기능을 제거했을 때 사용자 만족도, 유지율, 성능에 대한 A/B 테스트 데이터. DHH의 주장을 실증적으로 검증.
- 학습 시간 vs 생산성 트레이드오프: Vim/Git을 배우는 데 걸리는 시간 vs 평생 생산성 증가를 정량화하는 종단 연구. 학습 투자가 실제로 보상받는지.
추가 연구가 필요한 영역
- AI 도구 시대의 직교성: Copilot, ChatGPT 같은 AI가 복잡한 명령을 자연어로 번역할 수 있다면, 직교적 설계의 학습 곡선 장벽이 제거되는가? 아니면 새로운 복잡도 소스가 되는가?
- 모바일 우선 세계: 연구된 대부분 제품이 데스크탑 시대에 탄생. 모바일 우선 환경에서 직교적 설계가 어떻게 적용되는가? 터치 인터페이스의 제약이 다른 설계 원칙을 요구하는가?
- 협업 vs 개인 도구: 연구된 많은 도구가 개인 사용에 최적화(Vim, Git CLI). Figma, Notion 같은 협업 중심 도구에서 직교성이 어떻게 나타나는가?
- 규제 복잡도: GDPR, 접근성 요구사항, 보안 표준이 강제로 복잡도를 추가하는 도메인. 이런 환경에서 직교적 설계가 가능한가, 아니면 복잡도가 불가피한가?
결론
직교적 설계는 우연의 산물이 아니라 의도적 선택과 끊임없는 거절의 결과다. Vim, Git, SQLite, Unix 도구가 수십 년간 지배적 지위를 유지하는 이유는 3-10개 직교적 프리미티브가 조합으로 무한한 가능성을 창출하기 때문이다. 하지만 이는 가파른 학습 곡선, 초기 개발 속도 저하, 대중적 매력 희생이라는 트레이드오프를 요구한다.
핵심 교훈: 덜어내고, 기다리고, 조합하라. Rich Hickey의 "생각하라, 타이핑하지 말라", DHH의 "한 번에 하나씩, 빌드하며 사용하라", McIlroy의 "뭘 제거할 수 있을까?"가 하나의 메시지로 수렴한다. 직교적 설계 역량은 코드 카타, 설계 카타, 아키텍처 카타를 통한 의도적 연습과 "아니요"라고 말하는 용기로 키워진다.
미래 질문: AI 시대에 직교적 설계의 학습 장벽이 제거될까, 아니면 새로운 형태의 복잡도가 등장할까? 모바일 우선, 협업 중심, 규제 복잡도 환경에서 같은 원칙이 적용될까? 성공 사례의 생존자 편향을 넘어, 실패한 직교적 설계를 연구해야 충분조건을 이해할 수 있다.
단 하나 확실한 것: 복잡도는 죽인다. 모든 스프린트가 과거 작업 재수행에 관한 것이 된다면, 이미 졌다. 직교적 설계는 그 싸움에서 이기는 방법이다.