Ask HN: 소프트웨어 설계를 배우기에 좋은 최고의 코드베이스는 무엇인가요?
(news.ycombinator.com)- 소프트웨어 설계 능력을 향상시키고자 노력하고 있는데, 기존의 잘 설계된 코드베이스를 연구해 보라는 권유를 받았음
- 공개적으로 접근 가능한 코드베이스 중 소프트웨어 설계의 골드 스탠다드로 여겨지는 것은 어떤게 있는지 궁금함
1. 추천 코드베이스
-
대형/대표 프로젝트
- Git, Postgres, CPython
- Linux Kernel 의 "lieutenants model"
- UNIX v6, BSDs
-
프레임워크/라이브러리
- Spring Framework
- Laravel
- Rust std 라이브러리
- Codemirror 6
- 시스템/서버
- 게임/특수 사례
-
교육용/학습 자료
- xv6 (MIT OS 수업)
- pytudes (Peter Norvig)
-
기타
- Monocypher (암호화 라이브러리)
- Tcl 언어 구현
2. 코드 읽기 vs 문서/설계 학습
-
코드만으로 한계
- 코드베이스는 구현을 보여주지만 디자인 의도나 트레이드오프는 숨겨져 있음
-
설계 문서 중요성
- ADR(Architectural Decision Records), Rust RFCs, Python PEPs 같은 의사결정 기록이 디자인 학습에 훨씬 유익
- 디자인 문서 작성 자체가 훈련이 될 수 있음
-
책·문헌 추천
- The Architecture of Open Source Applications
- Code Reading (Spinellis)
- Beautiful Code (O’Reilly, ISBN-10: 0596510047)
- Refactoring / Legacy Code 관련 서적
3. 실습 중심 학습론
-
경험과 시행착오
- 디자인은 문제를 반복적으로 겪고 피하는 법을 배우면서 익히는 것
- 코드 읽기만으로는 학습이 되지 않고, 직접 작성하고 실패를 해결하는 과정에서 배움
-
흥미 기반 학습
- 자신이 흥미 있는 프로젝트를 만들어야 깊이 배우게 됨
-
실패 비용이 낮은 특성
- 소프트웨어는 물리적 엔지니어링보다 실패 비용이 낮아 시도와 실패를 통한 학습이 효과적
4. 소프트웨어 엔지니어링 성격 논쟁
-
미성숙한 공학론
- 다섯 명의 엔지니어가 모이면 다섯 가지 다른 해법이 나오는 것은 공학으로서 미성숙함의 증거
-
실험 친화적 특성론
- 소프트웨어는 제약이 적어 다양한 해법이 존재하고, 물리 공학처럼 정답이 고정되지 않음
-
예술과 공학의 경계
- 디자인은 미적 요소를 가진 예술적 행위이기도 하지만, 기능적 요구를 만족하는 측면에서는 공학
- 소프트웨어는 예술적 유연성과 엔지니어링적 엄밀성 사이에 놓여 있음
5. 대안적 학습 방법
-
나쁜 코드 분석
- 잘 설계된 코드뿐 아니라 부실한 코드베이스를 고쳐보는 것도 큰 학습 효과
-
자신의 코드베이스 학습
- 팀 내부 코드베이스를 가장 많이 배울 수 있는 자료로 꼽음
- 단, 팀 코드가 부실할 경우 외부 사례 병행 필요
-
도메인 맞춤 학습
- 자신이 풀고 싶은 문제와 유사한 코드베이스를 읽는 것이 가장 효과적
주요 인사이트
- 잘 설계된 코드베이스는 도움이 되지만, 학습은 설계 의도를 이해하고 시행착오를 겪으며 병행해야 함
- 코드 읽기 자체보다 설계 문서와 의사결정 기록이 핵심 학습 자료임
- 대표적인 고품질 프로젝트(Git, Postgres, CPython, Rust std 등) 는 학습 가치가 높음
- 좋은 코드뿐 아니라 부실한 코드와 자신의 코드에서 배우는 것이 장기적으로 더 실질적임
주요 댓글 정리
대표적 코드베이스 추천 (CraigJPerry)
-
Postfix mail server
- 보안 중심 아키텍처로, 마이크로서비스 개념 이전에 이미 유사한 구조를 보여줌
- 현대적 마이크로서비스가 대규모 조직 분산에 중점을 둔다면, Postfix는 보안과 단순성을 위해 설계됨
-
Spring Framework
- 엔터프라이즈 환경 Java 개발자의 요구를 깊이 고려한 문화가 반영됨
- 사용자 중심 설계 접근을 배울 수 있음
-
Git
- 객체 데이터베이스(블롭, 트리, 커밋)와 레퍼런스 개념을 이해하면 나머지는 점진적 확장임
- 핵심 개념의 일관된 확장이 좋은 설계 사례로 제시됨
-
Varnish
- 고성능 리버스 프록시이면서, 학습 도구로 활용될 수 있을 정도로 잘 구성된 코드베이스
-
Linux Kernel Lieutenants Model
- 코드베이스는 아니지만, 대규모 소프트웨어 관리 모델로서 참고할 가치가 있음
- 단순히 "잘 설계된 코드"라기보다 디자인 의사결정이 강한 인상을 남긴 사례들임
실무 코드베이스 학습 강조 (crystal_revenge)
- 가장 큰 학습 가치는 자신의 팀 코드베이스에서 얻을 수 있음
- 실제 요구사항과 구현 간의 혼란스러운 연결 과정에서 좋은/나쁜 선택을 동시에 경험하게 됨
- 현실적 제약 중 가장 큰 요소는 시간 압박이며, 이상적 설계와 현실 사이의 균형을 익히는 것이 핵심
- 좋은 소프트웨어란 사용자 요구를 해결하는 것이며, 반복 경험을 통해 성공 가능성을 높이는 설계를 배우게 됨
과거 논의와 자료 링크 (sprobertson)
- HN에서 같은 주제가 여러 차례 다뤄졌음
코드 vs 설계 문서 (alphazard)
- 코드베이스는 구현의 결과물일 뿐, 설계 자체는 아님
- 설계 학습에는 디자인 문서 작성이 더 효과적임
- 문서는 다른 사람이 그대로 구현할 수 있을 정도로 명확해야 함
- 대안을 열거하고 왜 배제했는지 기록하면 설계 고려의 증거가 됨
- 좋은 디자이너는 더 넓은 설계 공간을 고려하고, 적절한 지점을 선택하는 사람임
전체 시스템 이해 강조 (RossBencina)
- 코드베이스 전체를 이해하는 과정은 매우 가치 있음
- 단순히 잘 설계된 코드뿐 아니라 시스템의 큰 그림을 보는 훈련이 됨
- UML 등 다이어그램을 통해 관계를 시각화하는 것이 도움됨
- 학습 접근법:
- 자신이 개발 중인 것과 유사한 소프트웨어의 코드를 읽는 것이 효과적
- 이미 잘 아는 도메인의 코드(웹 프레임워크, 웹 서버, Python 표준 라이브러리, VSCode 등)를 시작점으로 추천
- 처음에는 작은 프로그램, 익숙한 도메인부터 접근하는 것이 좋음
좋은 설계의 기준 (mamcx)
- 좋은 설계는 목표와 아이디어, 코드베이스는 그것의 구현 정도를 보여줌
- 좋은 설계는 단순히 "빠르다, 안전하다"는 수식어가 아니라 구체적 고려와 트레이드오프 기록을 포함해야 함
- 사례: Erlang, 초기 Pascal, 다수의 RDBMS 설계에서 이러한 특징을 관찰 가능
- Rust의 std 라이브러리는 보안과 일관성을 강조하며 코드와 문서가 이를 충실히 반영하는 좋은 학습 자료
보이지 않는 설계 결정 (ben30)
- 잘 설계된 코드베이스를 볼 때 가장 중요한 부분은 보이지 않는 것임
- 복잡성 배제, 불필요한 추상화 지양, 특정 패턴 거부 같은 부재의 결정이 핵심
- 이를 보완하기 위해 ADR(Architectural Decision Records) 를 활용
- 대안과 그 배제 이유, 선택 근거를 기록하여 맥락을 남김
- 향후 유지보수자와 AI 도구 모두에게 큰 도움을 줌
- 학습 시, 단순 코드 외에도 ADR·RFC·PEP 등 설계 의사결정 문서가 함께 있는 프로젝트를 살펴보는 것이 효과적
express.js 만든 TJ 스소가 깔끔하고 아름답게 설계되었다는 Evan You (Vue.js, Vite 제작자) 의 인터뷰가 있어서 몇번 코드 리딩 해봤는데 큰 그림까지 이해할 수는 없었지만 전반적으로 코드가 복잡하지 않고 깔끔하게 딱 필요한 로직만 짜여져있다는 느낌을 많이 받았음
주석도 잘 달려 있어서 10년 전 코드지만 타입 추론이나 DTO 포맷 알기 좋았음
Hacker News 의견
-
나만 그런 건지는 모르겠지만, 실제로 여러 번 문제에 부딪혀보고 어떻게 피해갈지 스스로 터득하는 방식이 가장 효과적임을 느낌. 그러다 보면 자연스럽게 앞으로 어떤 문제가 생길지 머릿속에서 시뮬레이션할 수 있게 되고, 결국 디자인이라는 것도 다양한 미래 문제들을 미리 예측해서 피하고, 어떤 문제를 어느 정도의 노력으로 피할 건지, 한 번의 디자인으로 여러 문제를 해결할 수 있는지 등의 트레이드오프를 신중하게 따지는 판단임
-
나도 마찬가지임. "연습문제 풀기"나 "코드베이스 공부하기" 같은 방식은 나한테 맞지 않았음. 내가 정말 흥미 있는 걸 만들어갈 때, 예시에서 정확함과 꼼꼼함을 추구하면서 자연스럽게 배움. 근데 가끔씩은 아직 내 실력이 부족하다고 생각됨. 마치 책 읽듯이 코드를 술술 읽어서 머릿속에 그 동작이 그려진다면, 공부 자체도 더 재미있을 거라고 생각함
-
여러 번 문제에 부딪혀보며 배운다는 이야기를 듣고 느낀 점은, 소프트웨어 엔지니어링 분야가 아직 성숙하지 못했다는 것임. 만약 다리나 집을 그런 식으로 짓는다면 어떨까, 아니면 외과의사가 그런 식으로 훈련된다면 어떨까 상상해보기만 해도 위험함. 시간이 지나면 표준이나 규범이 자리 잡겠지만, 지금은 그야말로 유동적인 상황임. 소프트웨어 엔지니어 다섯명을 모아놓고 문제를 제시하면 다섯 개의 전혀 다른 해결책이 나올 뿐만 아니라, 어떤 방법이 옳은지에 대해 강하게 의견 충돌이 생김. "좋은 해법은 보면 알아본다"라는 태도만으로는 제대로 된 엔지니어링이 될 수 없다고 생각함
-
나 역시 지금까지 이 방식으로 꾸준히 학습해왔고 앞으로도 계속 그럴 것임. 실제 프로덕션 코드로부터 배우는 건 내겐 새로운 도전이 될 듯함. 얼마나 가치 있을지는 모르겠지만 어쨌든 재미는 있을 것 같음
-
마치 운전 연수를 처음 차에 올라타서 사고를 내고, 그 뒤로 반성해서 다음엔 사고 안 나게 차 몰아본다는 식과 비슷하다고 생각함. 실제로는 이 두 가지 방법이 모두 필요함. 우리가 일반 도로 주행 시에는 한계를 넘는 상황이 거의 없어서 바로 적용되긴 힘들지만, 레이싱같은 경우에는 도대체 어디까지 밀어붙일 수 있는 한계선이 어디인지 정확히 알아두는 게 필수임. 물론 우리의 직업을 경기처럼 취급할 필요는 없다고 봄. 하지만 책을 안 읽고 공부를 안 하면 말 그대로 아주 오랜 시간이 걸릴 뿐만 아니라 사고와 고장도 끝이 없을 것임. 그래서 나는 무조건 읽고 또 읽으라고 말하고 싶음. 당장에는 그 필요성을 못 느낄 수도 있지만, 나중에 언젠가 경험을 쌓으면서 그 지식이 어디선가 반드시 쓰일 거고, 내리막길에서 처벌질하며 저단 기어로 변속해야 하는 걸 처음 배운 상황처럼 당황하지 않을 수 있음
-
이게 바로 핵심임
-
-
이 질문을 듣고 가장 먼저 드는 생각은 "팀의 코드베이스"임. 실제 문제에 대해 좋은 해법과 나쁜 해법이 각각 왜 채택됐는지 깊이 이해하는 것만큼 소프트웨어 디자인을 효과적으로 배우는 길은 없음. 소프트웨어란 본질적으로 유저 요구사항과 기계의 동작 사이를 연결해주는 복잡한 중간층 그 자체임. 만약 이 혼란이 없었다면 이미 자동화됐을 것이고, 소프트웨어 자체가 필요 없게 됐을 것임. 소프트웨어란 어떤 이상형만을 좇다보면 오히려 나쁜 의사결정을 자주 하게 됨. 실제로는 "왜 이런 압력에 의해 특정 선택이 이뤄졌는가"를 깨달으며 시행착오를 줄이게 됨. 동시에 빠르고 효과적으로 일하는 실전적인 방법론을 익혀야 함. 현실에서 가장 큰 도전은 시간 제한임. 이건 이론적인 소프트웨어 설계에서 거의 다뤄지지 않는데, 현실적으로는 항상 코드를 빨리 내야 한다는 압박을 받으면서 작업하게 됨. 하고 싶은 방식이나 최선의 방법을 쓸 시간이 부족한 경우가 많음. 좋은 소프트웨어란 유저의 실질적 니즈를 풀어주는 소프트웨어임. 앞으로 성공적인 실행을 더 자주 만들어내는 디자인 해법들이 존재하고, 그것들을 찾는 최선의 길은 실제 내가 작성하는 코드를 깊이 살펴보는 것임
-
만약 질문자가 자신의 팀 소프트웨어가 엉망이라고 느껴서 외부의 조언을 구하려는 경우라면 어떻게 해야 할까? 아니면 단순히 대학생이 질문하는 것이라면?
-
구현에 필요한 시간도 디자인 퀄리티를 판단하는 척도가 될 수 있다는 건 생각 못해봤지만, 정말 타당하다고 느낌. 나 역시 내 팀 코드베이스에서 엄청 많이 배우고 있음. 그중 대부분은 뛰어난 디자인에서는 좋은 것들을, 그렇지 못한 부분에서는 직접 구글링하면서 계속 배우게 됨
-
-
몇 년 지난 자료이긴 하지만 많은 오픈 소스 프로젝트 리더들이 기고한 "The Architecture of Open Source Applications" 시리즈가 있는데, 온라인에서 무료로 볼 수 있음
https://aosabook.org/en/index.html -
해당 질문은 이미 여러 번 나와서, 참고할 수 있는 링크들을 모아봄
-
Yanderedev 소스 코드
-
나는 정답을 말할 만큼 자격이 충분하진 않지만, 약 15년 전 "Code Reading"이라는 책을 정말 재미있게 읽었음. 이 주제와 딱 들어맞는 책임
https://www.spinellis.gr/codereading/
목차 참고: https://www.spinellis.gr/codereading/toc.html
유사한 이름의 책도 있었던 것 같은데 정확히 기억은 안 남 -
사실상 코드베이스에는 디자인이 아닌 구현이 담기는 경우가 더 많음. 예를 들어 다른 언어로 완전히 갈아엎더라도 디자인만은 유지될 수 있음. 디자인 문서 작성 연습을 추천함. 문서가 어떤 모양이어야 하는지 신경 쓰지 말고, 템플릿에 얽매일 필요도 없음. 무엇보다 중요한 건 이 문서를 다른 사람이 받아들고 그대로 구현할 수 있어야 한다는 점임. 그리고 문서 자체가 "고려의 흔적" 역할을 할 수 있음. 어떤 방식을 선택하고, 다른 대안이 있었지만 왜 그걸 선택하지 않았는지 명확히 남겨두면 됨. 미리 대안을 인정하고 비교해둠으로써 독자에게 충분히 고민했다는 신뢰를 줄 수 있음. "좋은" 시스템 설계자가 하는 일은 남들보다 더 큰 디자인 영역을 살펴보고, 일관성 있게 좋은 포인트를 찾아내는 것임. 문제를 하나 정하고, 다양한 디자인 공간을 실험해보고, 그중 어느 것이 더 나은지 이유를 설명해서 다 기록하면 됨
-
가장 먼저 "내가 풀고자 하는 문제는 무엇인가?"라는 질문부터 출발해야 함. 그 문제를 해결한 코드베이스를 찾아서 실제로 어떻게 구현했는지 집중적으로 분석하기. 좋은 디자인은 특정 도메인 상황과 아주 밀접하게 엮여 있다는 사실을 명심해야 함. Wonham의 Internal Model Principle도 코드에 해당된다고 생각함. 예를 들어, 임베디드 타겟을 위한 단위 테스트 문제를 해결하고 싶어서 관련 오픈 소스 프로젝트를 분석했고, 각 코드가 어떻게 작성됐는지 그 이유를 비판적으로 살펴봤음. 직접 나만의 솔루션을 만들면서 또다시 이전 코드들을 참고해가며 내 도메인 이해도가 깊어질수록 더 많은 걸 배워가고 있음
-
내 경험(소프트웨어 30년, 아키텍처 실무 25년, MIT 시스템 아키텍처 석사)으로는 추상적으로 "좋은" 디자인이란 원래 존재하지 않음. 분명히 나쁜 설계(안 좋은 결과를 초래하는 디자인)는 있지만, "좋은"의 기준은 맥락에 따라 달라짐. 무엇을 만드는지, 안전/보안 같은 요구사항, 그리고 무엇보다 실제로 구현하는 팀과 팀의 구조가 가장 큰 영향을 미침. 주니어들만 모인 팀에서는 정교한 설계를 곡해해서 망칠 수도 있음. Conway의 법칙처럼 개발팀의 구조가 소프트웨어에 그대로 반영된다고 봄
-
소프트웨어 디자인을 배워가면서 확실히 깨달은 점은 만능 해답이 없다는 사실임. 그런 게 있으면 참 좋을 텐데, 다양한 아키텍처와 패러다임 속에서 최적 해법을 고르는 게 답답할 때도 있음. 그래도 요구사항만 제대로 반영해도 선택지는 꽤 줄어듦. 지금은 안전성이 특별히 중요한 임베디드 시스템을 다루고 있는데, 이 환경 덕분에 다른 상황에서는 아예 쓸 일 없는 결정을 종종 하게 됨
-
결국 핵심은 정말 어처구니없는 타협안만 피하고, 최악의 선택들도 넓은 시야로 볼 때는 피해가는 것임. 현장에서 늘 느끼는 건, 최고의 아키텍처라기보다는 "근본적으로 나쁜 결정 피하기"의 연속 싸움이라는 점임
-
-
예전에 아주 간단한 추천 목록을 만든 적 있는데, 아직도 유효함
https://medium.com/@012parth/…