40P by GN⁺ | ★ favorite | 댓글 4개
  • 대규모 시스템의 실질적 설계 참여는 해당 코드를 직접 다루는 엔지니어만 가능하며, 추상적 조언은 대부분 무의미함
  • 일반적 설계 조언(generic design) 은 코드베이스를 모르는 상태에서 도메인만 이해한 채 제시되는 경우가 많음
  • 실제 업무에서는 구체적 제약과 일관성 유지가 설계 원칙보다 훨씬 중요하며, 코드의 현재 상태 이해가 핵심임
  • 새로운 시스템 설계나 회사 전체의 기술 방향 결정에서는 일반적 설계 원칙이 일정 부분 유용하게 작동함
  • 그러나 현장과 분리된 아키텍트 중심 설계 구조는 실패하기 쉽고, 설계를 제안한 사람이 결과에 책임을 져야 함

일반적 소프트웨어 설계의 한계

  • 대규모 시스템 설계에는 코드의 구체적 세부사항에 대한 깊은 이해가 필수
    • 추상적 조언은 실제 문제 해결에 거의 도움이 되지 않음
    • 실무에서는 일관성(consistency) 이 ‘좋은 설계’보다 더 중요함
  • 실제 코드베이스는 복잡하고 예측 불가능한 결과를 낳기 때문에, 안전한 변경을 위해 선택 가능한 구현 방식이 제한됨
  • 대규모 공유 코드베이스는 항상 여러 설계가 뒤섞인 중간 상태에 있으며, 이상적 목표보다 현재 코드의 결합 상태가 더 중요함
  • 대부분의 시스템은 전체 재작성(rewrite)이 불가능하므로, 내부 일관성과 엔지니어의 세심함에 의존해야 함

구체적 소프트웨어 설계의 특징

  • 효과적인 설계 논의는 시스템을 매일 다루는 소수의 엔지니어들 간의 대화에서 이루어짐
    • 논의 주제는 일반 원칙이 아니라 시스템의 세부 구조나 데이터 흐름 등 구체적 맥락 중심
  • 예를 들어 “DRY가 좋은가”가 아니라 “이 기능을 A 서브시스템에 넣을 수 있는가, B 정보가 C 컨텍스트에서 접근 가능한가” 같은 세밀한 기술적 논의가 이루어짐
  • 중요한 기여는 작은 오해나 코드 변경의 세부 영향을 바로잡는 데서 나옴

일반적 설계 조언이 유용한 경우

  • 새로운 프로젝트를 처음 설계할 때는 구체적 제약이 없으므로 일반적 원칙이 유용함
  • 여러 구현안 중 선택이 어려울 때 일반적 원칙이 결정의 기준(tie-breaker) 역할을 함
  • 회사 전체 수준의 일관성 유지에도 도움이 되며, 이는 공식적인 소프트웨어 아키텍트의 역할 중 하나임
  • 클라우드 vs 온프레미스, AWS vs Azure 같은 광범위한 기술 선택에서도 일반 원칙이 참고될 수 있으나, 여전히 구체적 제약을 무시할 수 없음

아키텍트와 ‘로컬 미니마’ 문제

  • 많은 기업이 현장 경험이 없는 아키텍트 중심의 추상적 설계 구조에 빠짐
    • 이 방식은 겉보기엔 효율적이지만, 실제로는 현장 엔지니어가 구현 불가능한 설계를 낳음
  • 아키텍트는 직접 구현하지 않기 때문에 성과에 대한 책임(skin in the game) 이 부족함
    • 설계가 성공하면 공을, 실패하면 실행팀의 탓으로 돌릴 수 있음
  • 이런 구조는 실질적 가치보다 형식적 설계 활동을 강화하는 경향이 있음

결론 및 제안

  • 유용한 설계 논의는 코드 단위 수준의 구체적 대화에서 이루어지며, 설계자는 반드시 코드베이스에 익숙해야 함
  • 일반적 아키텍처 원칙은 새 시스템 설계, 기존 시스템의 세부 결정 보조, 회사 차원의 기술 방향 설정에 한정되어야 함
  • 프로젝트 설계를 제안한 사람은 그 성공과 실패에 책임을 져야 하며, 실제로 코드를 다루는 엔지니어가 설계의 주체가 되어야 함
  • 이를 통해 실제 시스템을 이해하고 배포할 수 있는 사람이 진정한 설계자로 인정받을 수 있음
GeekNews Weekly에 포함된 글입니다. 에디터 코멘트 보기

댓글과 토론

이래서 요즘 구루들이 차라리 신입들이 에이전트 훨씬 잘쓴다고 하는구나. 오래 돈 벌게 해주던거라 언러닝을 안하네

아키텍처를 완성하는 프로세스를 개선한다면 충분히 문제 제기한 부분을 해결할 수 있지 않을까요?

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는 리드 엔지니어만큼 책임감을 가지지 않음

  • 내가 참여했던 최고의 앱들은 다음 세 가지 특징이 있었음

    1. 단순하고 효과적인 시스템을 중시함
    2. 개발자가 실제 사용자로서 모든 사용 사례를 이해함
    3. 발견한 문제를 바로 고칠 수 있는 자율성이 있음
      이 자유가 개발자 만족도와 제품 품질을 모두 높였음
  • 내 경험상, 대규모 코드베이스에서의 일관성 집착은 오히려 실수
    모듈마다 요구사항이 다르므로, 테스트 전략이나 네이밍도 달라야 함

  • 이상적인 경우, 개발자가 자신이 만든 소프트웨어의 실제 사용자이기도 해야 함
    그래야 오류나 불편을 직접 느끼고 개선 동기가 생김

    • 개발자가 고객 지원 단계를 거치지 않고 사용자 문제를 직접 볼 수 있는 통로가 필요함. 티켓, 포럼, SNS 등에서 얻는 인사이트가 크기 때문임
    • XP에서 고객을 팀에 포함시킨 건 훌륭한 아이디어였음. 그걸 비즈니스 대표로 대체한 건 Scrum의 원죄 중 하나임
  • 유지보수에 참여하지 않는 별도의 소프트웨어 아키텍트는 비현실적임
    프로젝트는 끊임없이 변하므로, 멀리서 지시만 하는 역할은 도움이 되지 않음

    • 나는 그런 역할이 있는 회사를 경험해본 적이 없음. 복잡한 소프트웨어는 진행 중인 체스 경기와 같음. 전략 원칙은 필요하지만, 실제 보드 상황을 모르는 조언은 무의미함

실제 업무에서는 구체적 제약과 일관성 유지가 설계 원칙보다 훨씬 중요하며, 코드의 현재 상태 이해가 핵심임

평소의 제 지론이라 가슴이 따뜻해지네요