06장: 소프트웨어 설계와 아키텍처 서론에서 이 파트 전체의 큰 그림을 소개했다면, 이 장은 그 출발점이 되는 질문부터 다룬다. 설계(Design)와 아키텍처(Architecture) 사이에는 오랫동안 많은 혼란이 있었다. 결론부터 얘기하면 둘 사이에는 차이가 없다.
설계 vs 아키텍처: 구분은 무의미하다
일반적인 인식
flowchart TB
subgraph Common [일반적인 인식]
ARCH[아키텍처
고수준의 무언가]
DESIGN[설계
저수준의 구조]
end
ARCH --- |"구분된다고 생각"| DESIGN
| 용어 | 일반적 인식 |
|---|---|
| 아키텍처 | 저수준의 세부사항과는 분리된 고수준의 무언가 |
| 설계 | 저수준의 구조 또는 결정사항 |
마틴의 결론
마틴은 아키텍트가 실제로 하는 일을 살펴보면 이러한 구분이 무의미하다고 결론짓는다(Martin, Clean Architecture, 2017).
flowchart TB
subgraph Reality [실제]
HIGH[고수준 구조]
LOW[저수준 세부사항]
FABRIC[단절 없이 이어진 직물]
end
HIGH --> FABRIC
LOW --> FABRIC
FABRIC --> SYSTEM[시스템의 구조 정의]
저수준의 세부사항과 고수준의 구조는 모두 소프트웨어 전체 설계의 구성요소다. 이 둘은 단절 없이 이어진 직물과 같으며, 이를 통해 대상 시스템의 구조를 정의한다.
의사결정의 연속성
개별로는 존재할 수 없고, 실제로 이 둘을 구분 짓는 경계는 뚜렷하지 않다. 고수준에서 저수준으로 향하는 의사결정의 연속성만이 있을 뿐이다.
| |
목표는 무엇인가?
그렇다면 이러한 의사결정의 목표는? 좋은 소프트웨어의 목표는?
마틴은 이렇게 말한다: 소프트웨어 아키텍처의 목표는 필요한 시스템을 만들고 유지보수하는 데 투입되는 인력을 최소화하는 데 있다(Martin, Clean Architecture, 2017).
설계 품질의 척도
설계 품질을 재는 척도는 고객의 요구를 만족시키는 데 드는 비용을 재는 척도와 다름이 없다.
flowchart LR
subgraph Good [좋은 설계]
G1[낮은 비용]
G2[수명 끝까지 유지]
end
subgraph Bad [나쁜 설계]
B1[출시마다 비용 증가]
B2[성장 멈춤 또는 파산]
end
| 설계 품질 | 비용 패턴 |
|---|---|
| 좋은 설계 | 비용이 낮고 시스템 수명 끝까지 낮게 유지 |
| 나쁜 설계 | 새로운 기능 출시할 때마다 비용 증가 |
사례 연구: 실제 회사의 데이터
마틴은 원저 1장에서 실제 컨설팅 경험을 근거로 이와 유사한 4개의 그래프(엔지니어 수·생산성·코드 라인당 비용·출시별 생산성)를 제시하며 나쁜 설계의 결과를 보여준다. 아래 수치는 그 패턴을 예시로 재구성한 것으로, 원저 도표의 정확한 값이 아니라 “무슨 일이 벌어지는가"라는 형태를 보여주기 위한 것이다.
1. 엔지니어링 직원 수의 증가
xychart-beta
title "엔지니어링 직원 수 증가 추이"
x-axis [R1, R2, R3, R4, R5, R6, R7, R8]
y-axis "직원 수" 0 --> 100
line [5, 10, 20, 35, 50, 65, 80, 95]
이러한 추세를 보면 분명 굉장한 성공을 이뤄냈음을 가리키는 지표라고 여길 것이다.
2. 같은 기간의 생산성
하지만 같은 기간의 생산성(코드 라인 수)을 보면:
xychart-beta
title "출시별 코드 라인 수 (생산성)"
x-axis [R1, R2, R3, R4, R5, R6, R7, R8]
y-axis "코드 라인" 0 --> 100
line [50, 80, 90, 92, 93, 94, 94, 95]
무언가가 명백히 잘못되었다. 매번 새로운 기능을 출시할 때마다 개발자의 수는 지속적으로 증가했지만, 코드 생산성은 마치 한 곳으로 수렴하는 것처럼 보인다.
3. 코드 라인당 비용
가장 두려운 그래프:
xychart-beta
title "코드 라인당 비용"
x-axis [R1, R2, R3, R4, R5, R6, R7, R8]
y-axis "비용" 0 --> 100
line [5, 10, 20, 30, 45, 60, 80, 95]
| 출시 | 비용 변화 |
|---|---|
| 1차 → 8차 | 약 19배 증가 |
이러한 방향으로는 지금 당장의 수익은 낼지 몰라도 결국 회사의 성장을 멈추게 하거나 완전히 망하게 만든다.
엉망진창이 되어 가는 신호
생산성 곡선
xychart-beta
title "출시별 생산성 하락"
x-axis [R1, R2, R3, R4, R5, R6, R7, R8]
y-axis "생산성 %" 0 --> 100
line [100, 80, 50, 30, 15, 8, 4, 2]
앞선 세 그래프(직원 수 증가·생산성 정체·비용 증가)를 시간축으로 이어보면 이 곡선이 나온다. 시스템을 급하게 만들거나, 결과물의 총량을 순전히 프로그래머 수만으로 결정하거나, 코드와 설계의 구조를 깔끔하게 만들려는 생각을 전혀 하지 않으면 생산성이 0으로 수렴한다.
개발자의 절망
개발자 입장에서 보면 이러한 현상은 큰 절망감을 안겨준다:
| |
위 코드가 보여주듯, 8시간 중 1시간만 새 기능에 쓰인다는 사실 자체보다 더 절망적인 것은 그 비율이 개인의 게으름이 아니라 시스템 상태의 결과라는 점이다.
- 모두가 전력을 기울여 열심히 일하고 있음
- 하지만 더 이상 발전이 없는 상황
- 개발자의 노력은 기능 개발보다는 엉망이 된 상황에 대처하는 데 소모
경영자의 시각
경영자 입장에서 월별 인건비 추이:
xychart-beta
title "출시별 월 인건비"
x-axis [R1, R2, R3, R4, R5, R6, R7, R8]
y-axis "인건비 (만 달러)" 0 --> 2000
line [50, 100, 200, 400, 700, 1000, 1500, 2000]
| 출시 | 인건비 | 결과물 |
|---|---|---|
| 1차 | 수십만 달러 | 많은 기능 |
| 8차 | 2천만 달러 | 거의 없음 |
경영자에게는 이 표가 가장 뼈아프다 — 지출은 40배 늘었는데 산출은 거의 0에 수렴했으니, 개발팀·경영진·고객 세 이해관계자 모두가 같은 원인(설계 품질 저하)의 서로 다른 증상을 겪고 있는 셈이다.
무엇이 잘못되었나?
흔해 빠진 거짓말 #1
“코드는 나중에 정리하면 돼. 당장은 시장에 출시하는 게 먼저야!”
flowchart TB
LIE1[거짓말: 나중에 정리하자] --> REALITY[현실: 절대 정리하지 않음]
REASON[이유: 시장 압박은 절대 수그러들지 않음]
REALITY --> MESS[엉망진창]
MESS --> ZERO[생산성 → 0]
시장 출시가 먼저라는 생각은 나름의 논리를 갖고 있어서 더 설득력 있게 느껴진다:
- 뒤에 여러 무리의 경쟁자가 뒤쫓고 있음
- 경쟁자보다 앞서 가려면 가능한 한 빠르게 달려야 함
흔해 빠진 거짓말 #2
“지저분한 코드를 작성하면 단기간에는 빠르게 갈 수 있고, 장기적으로 볼 때만 생산성이 낮아진다.”
| |
진실
마틴의 반박은 이렇다: 엉망으로 만들면 깔끔하게 유지할 때보다 항상 더 느리다. 시간 척도를 어떻게 보든지 관계없이 말이다(Martin, Clean Architecture, 2017).
flowchart LR
subgraph Truth [진실]
MESSY[엉망인 코드] --> SLOW[항상 더 느림]
CLEAN[깔끔한 코드] --> FAST[항상 더 빠름]
end
이 논지를 마틴은 한 문장으로 요약한다: 빨리 가는 유일한 방법은 제대로 가는 것이다(Martin, Clean Architecture, 2017).
재설계의 함정
개발자는 처음부터 다시 시작하여 전체 시스템을 재설계하는 것이 해답이라고 생각할지도 모른다.
| |
마틴의 경고는 이렇다: 자신을 과신한다면 재설계하더라도 원래의 프로젝트와 똑같이 엉망으로 내몰린다(Martin, Clean Architecture, 2017).
결론
어떤 경우에도 개발 조직이 할 수 있는 최고의 선택지:
flowchart TB
subgraph Solution [해결책]
S1[과신 인지 및 방지]
S2[아키텍처 품질 고민]
S3[좋은 아키텍처 이해]
end
subgraph Goal [목표]
G1[비용 최소화]
G2[생산성 최대화]
end
S1 --> S2 --> S3
S3 --> G1
S3 --> G2
- 조직에 스며든 과신을 인지하여 방지
- 소프트웨어 아키텍처의 품질을 심각하게 고민
- 좋은 소프트웨어 아키텍처가 무엇인지 이해
마틴은 이렇게 결론짓는다: 비용은 최소화하고 생산성은 최대화할 수 있는 설계와 아키텍처를 가진 시스템을 만들려면, 이러한 결과로 이끌어줄 시스템 아키텍처가 지닌 속성을 알고 있어야 한다(Martin, Clean Architecture, 2017).
비판적 시각
이 장의 사례 연구는 마틴이 컨설팅 경험에서 관찰한 패턴을 일반화한 것으로, 실명이 공개된 특정 기업의 감사된 재무 데이터가 아니라는 점에 유의해야 한다. “1차→8차 출시에서 생산성이 19배 비용 증가로 이어졌다"는 수치는 예시적 성격이 강하며, 모든 조직이 동일한 곡선을 그린다고 일반화할 수는 없다. 다만 “지저분한 코드가 단기적으로도 더 느리다"는 핵심 주장 자체는 여러 실증 연구(예: 기술 부채와 배포 빈도의 상관관계를 다룬 DORA 리포트류)에서도 폭넓게 뒷받침된다.
학습 목표
이 장을 읽은 후 다음을 할 수 있어야 한다.
- 설계와 아키텍처가 왜 동일한 연속체 위에 있는 개념인지 설명할 수 있다.
- 설계 품질을 “비용"으로 측정한다는 것이 실무에서 무엇을 의미하는지 설명할 수 있다.
- “나중에 정리하면 된다"는 흔한 거짓말이 왜 항상 틀리는지, 논거를 들어 반박할 수 있다.
판단 기준
이 장의 교훈을 실무에 적용할 때는 “완벽한 설계"와 “지금 당장 출시"라는 이분법에 빠지지 않는 것이 중요하다. 마틴의 주장은 “정리를 미루면 결국 더 느려진다"는 것이지, “모든 세부사항을 처음부터 완벽하게 설계해야 한다"는 것이 아니다. 즉 판단 기준은 “지금 이 결정이 나중에 되돌리기 얼마나 비싼가"이며, 되돌리기 쉬운 결정은 빠르게 내리고 되돌리기 어려운 결정(아키텍처 경계 등)에만 신중을 기하는 것이 실용적이다.
참고 자료
- Martin, R. C. (2017). Clean Architecture: A Craftsman’s Guide to Software Structure and Design. Prentice Hall.
다음 장에서는
다음 장에서는 소프트웨어가 제공하는 두 가지 가치, 행위(Behavior)와 구조(Structure)를 다룬다. 이 장에서 다룬 “설계 품질=비용"이라는 관점이 왜 장기적으로 기능 자체보다 더 중요할 수 있는지 살펴본다.
![Featured image of post [Clean Architecture] 07. 설계와 아키텍처란?](/post/clean-architecture/design-vs-architecture-definition/wordcloud_hu_d900184021f99a61.webp)
![[Clean Architecture] 05. 클린 아키텍처의 탄생](/post/clean-architecture/clean-architecture-birth-uncle-bob/wordcloud_hu_bf0cb2e1ba967d66.webp)
![[Clean Architecture] 06. 서론: 설계와 아키텍처](/post/clean-architecture/introduction-software-design-architecture/wordcloud_hu_87b701de2a933dab.webp)
![[Clean Architecture] 07. 설계와 아키텍처란?](/post/clean-architecture/design-vs-architecture-definition/wordcloud_hu_c4c64caad0472102.webp)
![[Clean Architecture] 08. 두 가지 가치: 행위와 구조](/post/clean-architecture/two-values-behavior-structure/wordcloud_hu_4d168768760e9072.webp)
![[Clean Architecture] 09. 프로그래밍 패러다임 서론](/post/clean-architecture/programming-paradigms-introduction/wordcloud_hu_2ead64fb71b1382e.webp)
![[Clean Architecture] 12. 객체 지향 프로그래밍](/post/clean-architecture/object-oriented-programming-polymorphism/wordcloud_hu_66479534e61250c6.webp)
![[Clean Architecture] 21. 컴포넌트: 배포 단위](/post/clean-architecture/components-deployment-units-history/wordcloud_hu_9119465747815465.webp)
![[Clean Architecture] 25. 아키텍처란?](/post/clean-architecture/what-is-architecture-system-lifecycle/wordcloud_hu_9cc50aa9a525e5fc.webp)