직접 만들고 고치지 않으면 소프트웨어를 설계할 수 없다
(seangoedecke.com)- 대규모 시스템의 실질적 설계 참여는 해당 코드를 직접 다루는 엔지니어만 가능하며, 추상적 조언은 대부분 무의미함
- 일반적 설계 조언(generic design) 은 코드베이스를 모르는 상태에서 도메인만 이해한 채 제시되는 경우가 많음
- 실제 업무에서는 구체적 제약과 일관성 유지가 설계 원칙보다 훨씬 중요하며, 코드의 현재 상태 이해가 핵심임
- 새로운 시스템 설계나 회사 전체의 기술 방향 결정에서는 일반적 설계 원칙이 일정 부분 유용하게 작동함
- 그러나 현장과 분리된 아키텍트 중심 설계 구조는 실패하기 쉽고, 설계를 제안한 사람이 결과에 책임을 져야 함
일반적 소프트웨어 설계의 한계
- 대규모 시스템 설계에는 코드의 구체적 세부사항에 대한 깊은 이해가 필수
- 추상적 조언은 실제 문제 해결에 거의 도움이 되지 않음
- 실무에서는 일관성(consistency) 이 ‘좋은 설계’보다 더 중요함
- 실제 코드베이스는 복잡하고 예측 불가능한 결과를 낳기 때문에, 안전한 변경을 위해 선택 가능한 구현 방식이 제한됨
- 대규모 공유 코드베이스는 항상 여러 설계가 뒤섞인 중간 상태에 있으며, 이상적 목표보다 현재 코드의 결합 상태가 더 중요함
- 대부분의 시스템은 전체 재작성(rewrite)이 불가능하므로, 내부 일관성과 엔지니어의 세심함에 의존해야 함
구체적 소프트웨어 설계의 특징
-
효과적인 설계 논의는 시스템을 매일 다루는 소수의 엔지니어들 간의 대화에서 이루어짐
- 논의 주제는 일반 원칙이 아니라 시스템의 세부 구조나 데이터 흐름 등 구체적 맥락 중심
- 예를 들어 “DRY가 좋은가”가 아니라 “이 기능을 A 서브시스템에 넣을 수 있는가, B 정보가 C 컨텍스트에서 접근 가능한가” 같은 세밀한 기술적 논의가 이루어짐
- 중요한 기여는 작은 오해나 코드 변경의 세부 영향을 바로잡는 데서 나옴
일반적 설계 조언이 유용한 경우
- 새로운 프로젝트를 처음 설계할 때는 구체적 제약이 없으므로 일반적 원칙이 유용함
- 여러 구현안 중 선택이 어려울 때 일반적 원칙이 결정의 기준(tie-breaker) 역할을 함
- 회사 전체 수준의 일관성 유지에도 도움이 되며, 이는 공식적인 소프트웨어 아키텍트의 역할 중 하나임
- 클라우드 vs 온프레미스, AWS vs Azure 같은 광범위한 기술 선택에서도 일반 원칙이 참고될 수 있으나, 여전히 구체적 제약을 무시할 수 없음
아키텍트와 ‘로컬 미니마’ 문제
- 많은 기업이 현장 경험이 없는 아키텍트 중심의 추상적 설계 구조에 빠짐
- 이 방식은 겉보기엔 효율적이지만, 실제로는 현장 엔지니어가 구현 불가능한 설계를 낳음
- 아키텍트는 직접 구현하지 않기 때문에 성과에 대한 책임(skin in the game) 이 부족함
- 설계가 성공하면 공을, 실패하면 실행팀의 탓으로 돌릴 수 있음
- 이런 구조는 실질적 가치보다 형식적 설계 활동을 강화하는 경향이 있음
결론 및 제안
- 유용한 설계 논의는 코드 단위 수준의 구체적 대화에서 이루어지며, 설계자는 반드시 코드베이스에 익숙해야 함
- 일반적 아키텍처 원칙은 새 시스템 설계, 기존 시스템의 세부 결정 보조, 회사 차원의 기술 방향 설정에 한정되어야 함
- 프로젝트 설계를 제안한 사람은 그 성공과 실패에 책임을 져야 하며, 실제로 코드를 다루는 엔지니어가 설계의 주체가 되어야 함
- 이를 통해 실제 시스템을 이해하고 배포할 수 있는 사람이 진정한 설계자로 인정받을 수 있음
실제 업무에서는 구체적 제약과 일관성 유지가 설계 원칙보다 훨씬 중요하며, 코드의 현재 상태 이해가 핵심임
평소의 제 지론이라 가슴이 따뜻해지네요
Hacker News 의견들
-
팀 회의에서 “DRY가 낫냐 WET가 낫냐” 같은 얘기가 아니라, “이 기능을 서브시스템 A에 넣을 수 있을까? 아니, 거기선 B 정보가 없고, 그걸 노출하려면 D를 다시 써야 하고…” 같은 식의 복잡한 의존성 논의가 이어지는 상황을 묘사함
익숙한 풍경이라며 농담처럼 여러 가상의 시스템 이름을 나열하고, 마지막에 YouTube 링크를 덧붙였음- “Wingman”이라니 웃김. 그런데 아직도 ISO8601을 지원하지 않는 소프트웨어 수가 너무 많음. Git조차 완전 호환이 아님
- 너무 현실적인 풍자 같음. 이상적으로는 한 팀이 하나의 서비스만 책임지는 게 좋다고 생각함. 하지만 요즘은 개발자 한 명당 마이크로서비스 네 개씩 맡는 시대라 피로감이 큼
- 이런 상황은 프로그래머가 비즈니스 시스템 설계까지 맡을 때 자주 생김. 시스템 분석가가 설계를 주도해야 함
-
30년 동안 개발을 해왔지만, 실제로 설계와 아키텍처에 일관된 노력을 들이는 경우를 거의 못 봤음
대부분의 ‘아키텍트’는 설계하지 않고, 시니어 개발자가 설계 후 피드백만 받는 구조임
평균 근속 2년이면 시스템의 일부만 이해한 채 설계를 하게 되고, 아키텍트는 그냥 승인만 하는 경우가 많음- John Ousterhout이 이 문제를 다루며 스탠퍼드에서 강의하고, 『A Philosophy of Software Design』이라는 책으로 확장했음. 강의 영상도 있음
- 예전에 ‘아키텍트’가 있는 프로젝트에 참여했는데, 실제로는 회의만 하는 사람이었음. 진짜 설계 조언을 해주는 사람은 없었음
- 2년이면 서브시스템을 완전히 바꾸거나 망칠 수도 있는 시간임. 요즘 소프트웨어는 그만큼 빠르게 변함
- 2~3년이면 50~100명 규모의 코드베이스를 꽤 깊이 이해할 수 있음. 그 뒤에 아키텍처 개선을 주도할 기회를 주면 회사가 기술적으로 성장할 수 있음. 아키텍트는 이런 아이디어를 조율하고 일관성 유지를 보장하는 역할이어야 함
-
‘Generic Software Design’은 구현 방향을 잡는 데 유용함. 공통 언어와 프레임을 제공해 문제 해결을 쉽게 함
하지만 실제 구현은 계획과 달라질 수 있음. Naur의 프로그래밍 이론처럼, 시스템의 진짜 지식은 개발자의 머릿속에 있음 -
“대규모 코드베이스에서는 일관성이 좋은 설계보다 중요하다”는 말은, 바로 그 일반화된 조언의 함정임
일관성만 강조하면 나쁜 습관이 그대로 유지됨- 우리 회사는 반대로 너무 자유로워서 문제임. 각자 자기 방식으로 만들어서 Redux 한 구석, 다른 쿼리 라이브러리 한 구석이 섞여 있음. 결국 유지보수가 더 힘들어짐
- 이건 단순히 코드 품질 문제가 아니라 조직 전체의 효율성 문제임. 일관성이 있으면 개발 속도가 빨라지고, 리뷰나 온보딩도 쉬워짐. 버그도 한 번에 고칠 수 있음
- 그 문장을 보고 움찔했음. 하지만 글을 끝까지 읽어보면 일관성의 본질은 통일성과 정확성에 있음
- 일관성을 유지하되, 점진적 개선이 중요함. 코드 만질 때마다 작은 개선을 하는 식으로 ‘쉬운 승리’를 쌓는 게 좋음
- “좋은 설계보다 일관성이 중요하다”는 말은 Boy Scout Rule에 어긋남. 일관성만 따지다 보면 전체 리팩터링으로 이어져 위험함
-
한쪽에는 현실을 모르는 ‘아키텍트’가 있고, 다른 한쪽에는 세부 최적화에만 몰두하는 Real Programmer가 있음
두 극단 모두 문제이며, 결정권자는 세부와 맥락을 모두 이해해야 함
관련 이야기로 The Story of Mel을 언급함 -
“설계를 한 사람이 프로젝트의 성공과 실패에 책임을 져야 한다”는 말에 동의함
이건 개발 방법론을 선택한 사람에게도 적용되어야 함. Scrum master는 리드 엔지니어만큼 책임감을 가지지 않음 -
내가 참여했던 최고의 앱들은 다음 세 가지 특징이 있었음
- 단순하고 효과적인 시스템을 중시함
- 개발자가 실제 사용자로서 모든 사용 사례를 이해함
- 발견한 문제를 바로 고칠 수 있는 자율성이 있음
이 자유가 개발자 만족도와 제품 품질을 모두 높였음
-
내 경험상, 대규모 코드베이스에서의 일관성 집착은 오히려 실수임
모듈마다 요구사항이 다르므로, 테스트 전략이나 네이밍도 달라야 함 -
이상적인 경우, 개발자가 자신이 만든 소프트웨어의 실제 사용자이기도 해야 함
그래야 오류나 불편을 직접 느끼고 개선 동기가 생김- 개발자가 고객 지원 단계를 거치지 않고 사용자 문제를 직접 볼 수 있는 통로가 필요함. 티켓, 포럼, SNS 등에서 얻는 인사이트가 크기 때문임
- XP에서 고객을 팀에 포함시킨 건 훌륭한 아이디어였음. 그걸 비즈니스 대표로 대체한 건 Scrum의 원죄 중 하나임
-
유지보수에 참여하지 않는 별도의 소프트웨어 아키텍트는 비현실적임
프로젝트는 끊임없이 변하므로, 멀리서 지시만 하는 역할은 도움이 되지 않음- 나는 그런 역할이 있는 회사를 경험해본 적이 없음. 복잡한 소프트웨어는 진행 중인 체스 경기와 같음. 전략 원칙은 필요하지만, 실제 보드 상황을 모르는 조언은 무의미함