---
title: "소프트웨어 아키텍처는 책보다 인센티브와 제약에서 배운다는 이야기"
published: 2026-05-12T09:30:21.000Z
canonical: https://jeff.news/article/2361
---
# 소프트웨어 아키텍처는 책보다 인센티브와 제약에서 배운다는 이야기

matklad가 과학 연구자에게 소프트웨어 설계와 아키텍처를 어떻게 배워야 하는지 답한 글이다. 핵심은 설계 지식만큼이나 조직의 인센티브, 기여자 구조, 빌드·테스트 비용 같은 현실 조건이 아키텍처를 결정한다는 점이다.

- matklad의 첫 결론은 꽤 현실적임. 소프트웨어 아키텍처는 책으로만 배우기 어렵고, 결국 직접 책임지고 만들어봐야 는다
  - 대학의 설계 수업도 들었지만 실제로는 “소방관 놀이하는 유치원생”에 가까웠다고 표현함
  - 본인을 진짜로 성장시킨 건 IntelliJ Rust에서 소프트웨어 리더십을 맡게 된 커리어상의 우연이었다고 함
  - 좋은 소식은, 호기심 있는 사람이라면 1원칙과 블로그 글들만으로도 꽤 멀리 갈 수 있다는 것

- 나쁜 소식은 Conway의 법칙임. 코드는 조직 구조와 인센티브를 꽤 정직하게 닮음
  - 글에서 인용한 문장은 “우리는 프로그래밍을 코드 작성처럼 말하지만, 코드는 아키텍처보다 덜 중요하고, 아키텍처는 사회적 문제보다 덜 중요하다”는 쪽에 가까움
  - 과학 코드가 산업 코드와 다른 이유도 단순히 개발 지식 부족 때문만은 아니라고 봄
  - “3개월 안에 논문을 내야 하는 박사과정” 같은 인센티브가 코드 품질을 크게 설명할 수 있다는 얘기임

- 그래서 설계자는 코드 구조만 볼 게 아니라 인센티브 구조도 봐야 함
  - 가끔은 프로젝트의 인센티브를 설계하거나 살짝 밀어볼 기회가 생기는데, 그때의 영향력이 엄청 크다고 함
  - TIGER_STYLE도 규칙 목록 자체보다, 그 규칙이 말이 되는 사회적 맥락이 핵심이라고 해석함
  - 하지만 대부분의 프로젝트에서는 인센티브가 마음에 들지 않더라도 바꾸기 어렵고, 결국 제약 안에서 최선을 찾아야 함

- rust-analyzer 사례가 이 글의 진짜 본론에 가까움
  - 프로젝트의 물리적 현실은 “깊고 넓다”였음
  - 깊다는 건 컴파일러라는 뜻이고, 넓다는 건 전통적인 IDE처럼 목적별 기능이 엄청 많다는 뜻임
  - 깊은 컴파일러 코어는 소수의 뛰어난 장기 기여자를 끌어들일 수 있음
  - 반면 자잘한 IDE 기능은 Rust를 배우는 사람들이 주말에 한두 시간 들여 자기 불편을 고치는 기여와 잘 맞음

- matklad가 rust-analyzer의 빌드 환경에 집착한 이유도 여기서 나옴
  - rustc를 빌드하지 않아도 되고, stable Rust에서 빌드되고, C 의존성이 없고, 전체 테스트가 몇 초 만에 끝나야 한다고 봄
  - 이건 단순한 개발자 경험 개선이 아니라 고임팩트 기여자를 끌어오기 위한 아키텍처적 선택이었음
  - 누군가 borrow checker 쪽을 고치려는데 빌드 시스템부터 씨름하게 만들면, 좋은 기여가 시작되기도 전에 꺾일 수 있다는 판단임

> [!IMPORTANT]
> 이 글의 핵심 문장은 “아키텍처는 코드 모양이 아니라 누가, 어떤 비용으로, 어디까지 기여할 수 있는지를 설계하는 일”에 가까움.

- rust-analyzer는 기능 영역과 코어 영역의 품질 기준도 다르게 잡음
  - 많은 독립 기능은 런타임에서 catch_unwind로 감싸서 기능별 실패가 전체 시스템으로 번지지 않게 함
  - 이런 기능 PR의 기준은 “happy path가 동작하고 테스트가 있다” 정도로 낮게 잡았다고 함
  - 대신 품질 문제는 기능 안에 격리되어야 하고, 사용자가 보는 런타임에서는 크래시가 보이지 않아야 함
  - 반대로 여러 기능을 떠받치는 core spine에서는 훨씬 더 깐깐하게 품질을 봤음

- 흥미로운 경고도 있음. 인센티브에 적응해서 만든 구조가 나중에 다른 미래를 맞을 수 있다는 것
  - rust-analyzer의 원래 동기 중 하나는 IntelliJ Rust 안에 별도 컴파일러를 또 쓰지 않기 위한 실험이었음
  - 더 나은 LSP 아키텍처를 프로토타입하고, 배운 내용을 rustc로 되돌리는 목표도 있었다고 함
  - 그런데 결과적으로는 “컴파일러가 하나 더 생긴 셈”이 됐다고 농담함
  - uutils도 Rust 학습자들의 목적지로 시작했다가 Ubuntu coreutils 구현체가 된 비슷한 사례로 언급됨

- 추천 자료 쪽에서도 “정답 책 하나”는 없다고 선을 그음
  - Gary Bernhardt의 Boundaries talk는 객체 수준 조언도 좋고, 메타 질문을 촉발한 자료라고 함
  - How to Test는 널리 인용되는 테스트 조언 중 상당수가 주술에 가깝다는 걸 인정하게 해준 자료로 언급함
  - Pieter Hintjens와 ZeroMQ 가이드는 Conway의 법칙식 사고를 배우는 데 도움이 됐다고 함
  - Software Engineering at Google과 Ousterhout의 The Philosophy of Software Design은 좋지만, 본인에게 완전히 판을 바꾼 책은 아니었다고 평가함

- 이 글이 특히 연구 코드나 사내 툴을 만지는 개발자에게 찔리는 이유는 명확함
  - “제대로 만들 시간이 없었다”는 말은 거의 모든 산업 프로젝트에도 해당함
  - 중요한 건 이상적인 아키텍처를 상상하는 게 아니라, 지금 프로젝트의 시간·기여자·빌드 비용·테스트 비용 안에서 무엇을 격리하고 무엇을 엄격히 볼지 정하는 것임
  - 결국 좋은 설계는 멋진 다이어그램보다 실패가 번지는 경로를 줄이고, 좋은 기여가 들어오는 경로를 짧게 만드는 쪽에 가까움

---

## 기술 맥락

- rust-analyzer 설계에서 중요한 건 모든 코드에 같은 기준을 적용하지 않았다는 점이에요. 컴파일러 코어처럼 여러 기능이 의존하는 부분은 엄격하게 보고, 독립 IDE 기능은 기여 장벽을 낮췄어요. 프로젝트의 깊이와 넓이가 다르니 품질 정책도 달라야 했던 거예요.

- 빌드가 빠르고 의존성이 적어야 한다는 조건은 단순 편의가 아니에요. 오픈소스에서는 기여자가 관심을 가진 순간에 바로 고칠 수 있어야 하거든요. rustc 빌드나 C 의존성 때문에 첫 실행부터 막히면, 잠재적인 좋은 기여가 사라져요.

- catch_unwind로 기능 실패를 격리한 것도 인센티브 설계예요. 작은 기능은 많은 사람이 쉽게 넣게 하되, 그 기능이 터져도 전체 언어 서버 상태를 망치지 않게 만든 거죠. 낮은 품질 기준을 허용하려면 그만큼 격리 경계가 선명해야 해요.

- 이 관점은 회사 코드에도 그대로 적용돼요. 모든 모듈을 최고 품질로 만들 수 없다면, 어디가 시스템의 척추이고 어디가 실험 가능한 잎사귀인지 먼저 나눠야 해요. 그 구분 없이 “클린하게 합시다”만 외치면 실제 제약을 못 이겨요.

## 핵심 포인트

- 소프트웨어 설계는 강의보다 실제 책임을 지고 만들면서 배우는 성격이 강함
- Conway의 법칙처럼 코드 구조는 조직과 기여자 구조를 따라가는 경우가 많음
- rust-analyzer는 깊은 컴파일러 코어와 넓은 IDE 기능을 서로 다른 품질 기준으로 나눠 설계함
- 좋은 아키텍처는 추상적 미학보다 누가 어떤 제약에서 기여할 수 있는지를 반영해야 함

## 인사이트

이 글은 ‘좋은 구조란 무엇인가’보다 ‘이 프로젝트에서 좋은 구조가 가능하려면 어떤 사회적 조건이 필요한가’를 묻는 쪽에 가깝다. 연구 코드든 오픈소스든 회사 코드든, 빌드 30분짜리 프로젝트에 좋은 기여자가 모이길 기대하는 건 솔직히 욕심이라는 얘기임.
