2.14

View in English

2.14 프로젝트와 저장소 구조

개요와 동기

프로젝트와 저장소 구조는 코드베이스의 물리적 조직입니다. 어떤 것이 어디에 있는지를 정하는 폴더, 파일, 명명 관례입니다. 저장소(흔히 “repo”로 줄임)는 프로젝트의 파일과 그 이력을 담는 버전 관리되는 컨테이너입니다. 프로젝트는, 관련된 여러 구성 요소를 묶을 때 솔루션이라고도 하며, 만들고 있는 소프트웨어의 논리적 단위입니다. 구조는 그 소프트웨어를 찾고, 이해하고, 바꾸는 데 쓰는 지도입니다.

작은 팀에서는 한 사람이 배치 전체를 머릿속에 담을 수 있습니다. 수백, 수천 명의 엔지니어, 잦은 팀 이동, 오가는 계약자가 있는 큰 팀에서는 다르게 조직된 모든 저장소가 새로운 인지 세금을 부과합니다. 낯선 저장소를 열 때, 설명서를 읽지 않고도 소스, 테스트, 문서, 배포 설정이 어디에 있는지 짐작할 수 있어야 합니다. 모든 저장소가 그 질문에 같은 방식으로 답하면 이동이 싸고 온보딩이 빠릅니다. 각 저장소가 눈송이(제각각)이면 모든 맥락 전환이 작은 조사 프로젝트로 바뀝니다.

기업과 정부 환경에서 일관된 구조는 통제와 보증의 관심사이기도 합니다. 원래 작성자가 떠난 지 여러 해 뒤에 일하는 경우가 많은 감사자, 보안 검토자, 장기 유지보수자는 명세 문서, 라이선스 파일, 보안 정책, 빌드 정의를 안정적으로 찾을 수 있어야 합니다. 예측 가능한 배치는 자동화 도구(스캐너, 의존성 분석기, 컴플라이언스 검사)가 시스템 포트폴리오 전체에서 같은 방식으로 작동하게 하기도 합니다. 그래서 이 장은 구조를 한 번 정해 어디서나 적용하는 관례로 다룹니다. 코딩 표준과 스타일(2.1장), 버전 관리와 소스 관리(2.6장), 문서화(2.7장)와 밀접하게 관련됩니다.

핵심 원칙

  • 최소 놀람의 원칙을 따르십시오. 배치는 경험 많은 엔지니어가 기대할 것과 맞아야 하므로, 외울 것이 없어야 합니다.
  • 저장소 간 일관성이 지역적 영리함을 이깁니다. 어디서나 충분히 획일적인 구조가 한 곳의 완벽한 구조보다 값집니다.
  • README는 앞문입니다. 신입은 그것만으로 방향을 잡을 수 있어야 합니다.
  • 명명을 통해 구조를 스스로 설명하게 하십시오. 폴더와 파일이 자기 목적을 알립니다.
  • 의지와 리뷰 코멘트가 아니라 스캐폴딩과 템플릿으로 구조를 시행하십시오.
  • 관심사를 물리적으로 분리하십시오. 소스, 테스트, 문서, 빌드, 배포는 별개의 예측 가능한 곳에 속합니다.
  • 의존성이 안정적인 핵심에서 변동성 있는 가장자리를 향해 한 방향으로 흐르도록 조직하십시오.

권장 사항

일관된 최상위 배치를 채택한다

모든 저장소가 해당하는 곳에서 사용하는 표준 최상위 폴더 집합을 정의하고 각각의 용도를 문서화하십시오. 흔하고 벤더 중립적인 관례에는 프로덕션 코드를 위한 소스 폴더(흔히 src), 자동 테스트를 위한 테스트 폴더(흔히 test나 tests), 문서를 위한 docs 폴더, 빌드 정의와 출력을 위한 build 폴더, 배포와 코드형 인프라(서버, 네트워크, 서비스의 기계가 읽을 수 있는 정의, 8.2장에서 다룸)를 위한 deploy 폴더, 자동화와 개발자 도구를 위한 scripts 폴더, 실행 가능한 샘플을 위한 examples 폴더, 요구사항과 설계 명세를 위한 spec이나 specification 폴더가 포함됩니다. 모든 저장소에 모든 폴더가 필요한 것은 아니지만, 관심사가 존재하는 곳에서는 기대되는 이름으로 기대되는 곳에 있어야 합니다.

README를 진입점으로 만든다

저장소 루트에 하나의 정식 시작점으로서 README 파일을 요구하십시오. 프로젝트가 무엇인지, 어떻게 빌드하고 실행하는지, 어떻게 테스트를 실행하는지, 더 깊은 문서를 어디서 찾는지, 누가 소유하는지, 어떻게 기여하는지를 밝혀야 합니다. README는 문서 집합 전체가 아니라 나머지를 가리키는 색인입니다(2.7장). 모든 신규 엔지니어, 감사자, 통합자가 가장 먼저 읽는 것이므로, 없거나 낡은 README는 결함으로 다루십시오.

편집기와 설정 파일을 표준화한다

모든 기여자가 일관된 동작을 자동으로 얻도록 공유 편집기와 도구 설정을 저장소에 체크인하십시오. .editorconfig 파일(공백, 들여쓰기, 줄 끝 규칙을 정의하는 단순하고 편집기에 구애받지 않는 파일)은 다른 편집기와 운영 체제에 걸쳐 기본 서식을 획일적으로 유지합니다. 버전 관리 시스템의 무시 파일(빌드 출력과 로컬 산출물이 절대 커밋되지 않도록)을 2.1장에서 설명한 공유 포매터 및 린터 설정과 함께 추가하십시오. 이 파일들은 저장소의 관례를 문서화만 하는 것이 아니라 활성화합니다.

명명과 폴더 관례를 정의한다

폴더와 파일의 명명 관례(대소문자, 구분자, 단수 대 복수, 테스트를 표시하는 것 같은 필수 접미어)에 합의하고 일관되게 적용하십시오. 이름은 의도를 드러내고 조직의 다른 곳에서 쓰는 도메인 어휘와 맞아야 합니다. 목표는 단순합니다. 경로가 의미를 전달해서, 폴더나 파일 이름을 읽으면 열지 않고도 안에 무엇이 있는지 알려 주어야 합니다.

계층과 의존성을 의도적으로 조직한다

코드베이스를 아키텍처 계층이 폴더 배치에 나타나고 의존성이 단일하고 합리적인 방향으로 흐르도록 구조화하십시오. 상위 수준의 정책이 하위 수준의 세부에 의존해서는 안 됩니다. 공유되고 안정적인 코드는 많은 모듈이 순환을 만들지 않고 닿을 수 있는 곳에 있어야 합니다. 계층화를 디렉터리 트리에 반영해 물리적으로 만들면 엔지니어가 그것을 존중할 가능성이 높아지고, 리뷰와 자동 의존성 검사에서 위반을 알아채기 쉬워집니다.

스캐폴딩과 템플릿으로 구조를 시행한다

시작 프로젝트의 자동 생성인 스캐폴딩을 제공해 새 저장소가 이미 올바르게 시작하게 하십시오. 템플릿이나 쿠키커터(몇 가지 질문에 대한 답으로 바로 쓸 수 있는 저장소를 생성하는 매개변수화된 프로젝트 골격)는 표준 배치, README, 설정 파일, CI 설정을 한곳에 부호화합니다. 엔지니어가 공유 템플릿에서 새 서비스를 만들면 일관성이 열망이 아닌 기본값이 되고, 템플릿의 개선은 미래의 프로젝트로 흘러갑니다.

규모에서 많은 저장소에 걸쳐 구조를 일관되게 유지한다

배치 자체를 다스려지는 표준으로 다루십시오. 다른 엔지니어링 표준(1.7장)처럼 중앙에서 유지하고 코드처럼 버전 관리하십시오(2.6장). 공개하고, 그것을 구현하는 템플릿을 제공하고, “표준”이 의미를 유지하도록 문서화된 예외 절차를 통해서만 일탈을 허용하십시오. 포트폴리오 규모에서 구조의 가치는 거의 모두 저장소 간 획일성에서 오므로, 표류가 관리해야 할 주된 위험입니다.

구조가 모노레포 대 멀티 레포 선택에 정보를 주게 한다

구조를 2.6장에서 다룬 저장소 경계 결정과 연결하십시오. 모노레포(많은 프로젝트를 담은 하나의 저장소)는 단일 트리를 탐색 가능하게 유지하도록 프로젝트와 공유 코드를 분리하는 분명한 내부 관례가 필요합니다. 멀티 레포 접근(프로젝트나 서비스마다 하나씩의 많은 작은 저장소)은 각 저장소가 독립해 있어도 친숙하게 느껴지도록 강한 저장소 간 일관성이 필요합니다. 어느 쪽이든 문서화되고 템플릿화된 구조가 탐색을 예측 가능하게 유지합니다. 경계 선택은 관례를 적용하는 곳을 바꾸지, 관례가 필요한지 여부를 바꾸지 않습니다.

장단점

선택장점단점
엄격한 조직 전체 표준 배치즉각적 친숙함. 이동 가능한 엔지니어. 획일적 도구특이한 프로젝트에는 가끔 맞지 않음. 거버넌스 필요
팀별 배치 자유지역 최적화. 높은 자율파편화. 비싼 맥락 전환. 일관되지 않은 도구
스캐폴딩과 템플릿기본적으로 올바른 저장소. 변경이 전파됨템플릿 유지보수. 생성된 저장소가 표류할 위험
깊은 계층 폴더 구조명시적 구조. 분명한 경계탐색 오버헤드. 긴 경로. 과설계 위험
평평하고 얕은 배치훑어보기 쉬움. 낮은 의식약한 분리. 프로젝트가 커지면 무너짐

지배적인 트레이드오프는 획일성 대 자율입니다. 단일 표준 배치는 코드베이스 사이를 오가는 많은 엔지니어의 마찰을 없애지만, 필요가 틀에 깔끔하게 맞지 않는 가끔의 프로젝트가 대가를 치릅니다. 큰 조직에서 친숙함의 집단적 이득은 거의 항상 그 지역적 손실을 능가합니다. 그래서 권장 자세는 경직된 획일성도 관리되지 않는 자유도 아닌, 강한 기본 표준에 문서화된 예외 경로(1.7장)를 더한 것입니다. 부차적 트레이드오프는 깊이 대 단순성입니다. 진짜 관심사를 분리할 만큼의 구조이되, 탐색이 빈 폴더를 헤치는 등산이 될 만큼은 아닙니다.

팀과 논의할 질문

  1. 엔지니어가 낯선 우리 저장소로 옮겨 가면, 테스트, 배포 설정, 소유자를 찾기까지 얼마나 걸립니까? 이것이 구조가 없애려고 존재하는 탐색 세금이며, 포트폴리오 규모에서는 합쳐서 심각한 엔지니어링 시간 손실이 되는 작은 증분으로 연간 수천 번 치러집니다. 최소 놀람의 원칙의 요점은 경험 많은 엔지니어가 설명서를 읽지 않고도 소스, 테스트, 문서, 배포가 어디에 있는지 짐작할 수 있어야 한다는 것이므로, 정직한 시험은 그 짐작이 여러분의 저장소 전반에서 성공하는가입니다. 실제 숫자를 회의에 가져오십시오. 낯선 내부 저장소 두세 개에서 방향을 잡는 데 걸리는 시간을 재거나, 신규 합류자가 첫 변경을 만드는 데 걸리는 시간의 온보딩 데이터를 끌어오십시오. 답이 인식의 몇 분이 아니라 조사의 며칠로 측정된다면, 눈송이 저장소의 비용을 정량화한 것이며, 모든 저장소가 공유하는 표준 배치에 대한 일회성 투자를 정당화합니다.

  2. 우리의 아키텍처 계층이 폴더 트리에 나타납니까, 아니면 의존성 순환이 평평한 배치 안에 숨어 있습니까? 구조는 찾기 쉬움 이상의 것입니다. 계층화를 물리적으로 만들면 엔지니어가 존중하고 리뷰어와 자동 의존성 검사가 위반을 알아챌 수 있는 반면, 평평한 더미는 변경이 위험해질 때까지 부적절한 결합과 순환이 눈에 띄지 않게 스며들게 합니다. 크고 오래 사는 시스템에서 이것이 상위 정책이 하위 세부에 조용히 의존하는 것을 막으며, 예방하기는 싸고 풀기는 비싼 바로 그런 침식입니다. 의존성 그래프를 가져오거나 빠른 검사를 돌려 보십시오. 순환이 있습니까, 안정적인 무언가가 변동성 있는 것에 의존합니까? 답은 계층을 디렉터리에 반영하고 자동 의존 방향 검사를 더하도록 이끌어, 경계가 누군가의 머릿속 모델에만 살지 않고 트리에서 보이고 파이프라인에서 시행되게 해야 합니다.

  3. 새 저장소는 템플릿에서 올바르게 시작합니까, 아니면 위키 페이지와 선의에 의존합니까? 스캐폴딩으로 시행되는 구조가 기본이고, 문서로 기술된 구조는 표류합니다. 현실은 페이지가 말하는 모습이 아니라 저장소를 생성하는 것을 따르기 때문입니다. 크거나 규제를 받는 조직에서 이는 보증의 관심사이기도 합니다. 모든 저장소가 공유 템플릿에서 생성되면, 보안 스캐너, 의존성 분석기, 감사자가 벤더와 세월을 가로질러 항상 같은 곳에서 라이선스, 보안 정책, 명세, 빌드 정의를 찾습니다. 증거를 가져오십시오. 최근 저장소 중 표준 템플릿에서 스캐폴딩된 것 대 손으로 조립된 것이 몇 개이며, 템플릿으로 만든 것은 이후 얼마나 표류했습니까? 행동은 템플릿을 저장소를 시작하는 유일한 쉬운 방법으로 만들고, 문서화된 예외 경로가 있는 버전 관리되는 표준으로 다스리고, 표류를 자동으로 탐지하는 것입니다. 구조의 가치는 거의 모두 획일성에 있기 때문입니다.

  4. 우리의 표준이 모노레포에 걸치는지 여러 별도 저장소에 걸치는지 결정했으며, 같은 관례가 그 경계의 양쪽에서 실제로 성립합니까? 저장소 경계 선택은 관례를 적용하는 곳을 바꾸지 관례가 필요한지를 바꾸지 않으며, 잘못하면 아무도 탐색할 수 없는 하나의 거대한 트리나 각각이 낯설게 느껴지는 저장소의 난립이 됩니다. 모노레포는 하나의 트리가 탐색 가능하게 유지되도록 프로젝트와 공유 코드를 분리하는 분명한 내부 관례가 필요하고, 멀티 레포 접근은 각 독립 저장소가 여전히 친숙하게 느껴지도록 강한 저장소 간 일관성이 필요합니다. 현재 목록을 가져오십시오. 저장소가 몇 개인지, 모노레포 안에서 공유 코드가 어떻게 분리되는지, 엔지니어가 큰 트리 안에서 프로젝트를 독립 저장소에서만큼 빨리 찾을 수 있는지의 시간 측정 시험입니다. 서로 다른 벤더가 별도 저장소를 전달하는 큰 기업이나 정부 프로그램에서는 관례의 어느 부분이 보편적이고 어느 부분이 경계에 특화되는지 의도적으로 정하십시오. 코드가 하나의 트리로 오든 쉰 개로 오든 감사자와 플랫폼 도구가 같은 방식으로 작동해야 하기 때문입니다.

  5. 구조 표준은 누가 소유하며, 프로젝트가 정말 맞지 않을 때 실제로 무슨 일이 일어납니까? 포트폴리오 규모에서 구조의 가치는 거의 모두 획일성에서 오므로, 진짜 위험은 소유자 없는 표준이 썩는 것과 모든 팀이 조용히 자기 배치를 발명할 만큼 모호한 예외 경로입니다. 긴장은 특이한 프로젝트에 맞지 않는 경직된 획일성과 모든 것을 파편화하는 관리되지 않는 자유 사이에 있으며, 건강한 답은 이름 있는 소유자가 다스리고 코드처럼 버전 관리되는, 강한 기본값에 문서화되고 감사 가능한 예외 절차를 더한 것입니다. 증거를 가져오십시오. 단일 책임 소유자가 있는지, 변경 로그가 있는 버전 관리되는 표준 문서가 있는지, 허용된 예외와 그 이유의 로그가 있는지, 현장에서 찾을 수 있는 문서화되지 않은 일탈의 수가 몇인지입니다. 기업과 정부 환경에서 아무도 기록하지 않은 예외는 통제 간극이므로, 각 일탈을 서면 정당화와 검토 날짜에 묶고, 배치를 의무화하는 조달 계약이 일탈을 누가 승인할 수 있는지도 명시하게 하십시오.

  6. README와 체크인된 설정 파일이 우리의 관례를 활성화합니까, 아니면 장식입니까? README는 앞문이고 체크인된 .editorconfig, 무시 파일, 린터 설정은 관례를 스스로 시행하게 하는 것이지만, 이는 가장 먼저 낡고 감사자나 신규 합류자가 프로젝트를 빌드하지 못할 때까지 가장 마지막으로 알아채는 것들입니다. 긴장은 최신으로 유지되는 간결한 README와 표류하는 철저한 README 사이, 그리고 사람이 코드를 올바르게 포맷하리라 신뢰하는 것과 공유 설정이 자동으로 시행하게 하는 것 사이에 있습니다. 표본을 가져오십시오. 저장소 다섯 개를 골라 몇 개의 README가 프로젝트가 무엇인지, 어떻게 빌드, 테스트, 실행하는지, 누가 소유하는지를 실제로 밝히는지, 몇 개가 개인의 습관에 의존하는 대신 공유 설정 파일을 지니는지 확인하십시오. 통합자, 보안 검토자, 장기 유지보수자가 다른 무엇보다 README를 먼저 읽는 크거나 규제를 받는 조직에서는, 없거나 낡은 앞문을 소유자가 있는 결함으로 다루고, 준수가 선의에 달려 있지 않도록 설정 파일의 존재를 자동으로 검사하십시오.

분야별 관점

스타트업. 속도가 이기니, 첫 저장소를 위한 단순하고 충분히 평평한 배치(src, test, docs, scripts, 채워진 README, .editorconfig, 무시 파일)에 합의하고 같은 날 오후 가벼운 템플릿으로 저장하십시오. 두 번째 서비스를 거기서 생성해 두 저장소가 모두 친숙하게 느껴지고 새 계약자가 눈송이를 역공학하는 대신 몇 시간 안에 온보딩되게 하십시오. 아직 필요 없는 깊은 계층과 무거운 거버넌스에 저항하십시오. 여기서 수익의 전부는 두 창업자와 한 계약자가 하나의 지도를 공유한다는 것입니다.

소기업. 플랫폼 전문가도 빠듯한 예산도 없으니, 하나를 발명하는 대신 언어나 프레임워크가 이미 가정하는 관례적 배치를 채택해, 기성 도구와 신규 채용자가 그것에 이미 훈련된 채 도착하게 하십시오. 직접 만드는 대신 스캐폴딩(프레임워크 생성기나 쿠키커터 템플릿)을 사고, 희소한 노력을 채워진 README를 최신으로 유지하는 데 쓰십시오. 그 README는 배치를 알던 한 사람이 떠나는 날에 대한 가장 싼 보험입니다.

대기업. 많은 팀과 수백 개 저장소에 걸쳐 목표는 획일성입니다. 버전 관리되는 구조 표준을 공개하고, 모든 새 서비스를 공유 템플릿에서 생성하고, 표류를 자동으로 탐지하고, 문서화된 예외 절차를 통해서만 일탈을 허용하십시오. 모든 저장소가 똑같이 보이므로, 새 팀으로 재배치된 엔지니어는 몇 시간 안에 생산적이 되고 포트폴리오 전체의 보안 및 의존성 스캐너는 항상 같은 곳에서 라이선스, 보안 정책, 빌드 정의를 찾습니다. 템플릿 유지보수와 표류 탐지를 명시적으로 예산에 잡으십시오. 그 유지가 표준을 규모에서 의미 있게 지키기 때문입니다.

정부. 조달, 투명성, 장기 책임성이 배치를 형성하니, 모든 벤더를 구속하는 전달 표준에 공통 구조를 의무화하십시오. 코드를 승인된 요구사항에 연결하는 specification 폴더, 루트의 라이선스와 보안 정책 파일, 코드형 인프라 정의를 담은 deploy 폴더를 요구해, 감사자가 모든 시스템에서 컴플라이언스 산출물을 같은 방식으로 찾게 하십시오. 서로 다른 벤더의 계약자가 모두 하나의 지도를 따르므로 계약이 끝난 뒤의 유지보수 비용이 훨씬 적고, 대중은 요구사항에서 실행 중인 코드까지의 방어 가능하고 검사 가능한 흔적을 얻습니다.

사례

스타트업. 세 명 규모의 스타트업이 첫 저장소를 위한 단순한 표준 배치(src, test, docs, scripts, 채워진 README, .editorconfig, 무시 파일)에 합의하고 가벼운 템플릿으로 저장합니다. 한 달 뒤 두 번째 서비스를 띄울 때 그 템플릿에서 생성하므로, 두 저장소가 이미 친숙하게 느껴지고 새 계약자는 한나절 만에 온보딩됩니다. 아직 필요 없는 깊은 폴더 계층에는 저항하고, 트리를 한눈에 훑을 수 있을 만큼 평평하게 유지합니다. 비용은 한나절의 설정이었고, 그렇지 않았다면 모든 미래의 저장소를 작은 조사 프로젝트로 만들었을 눈송이 난립을 면하게 해 줍니다.

대기업. 한 다국적 소매업체가 여러 언어에 걸쳐 수백 개의 서비스를 운영합니다. 플랫폼 팀이 버전 관리되는 저장소 구조 표준과 그것을 구현하는 프로젝트 템플릿 집합을 공개합니다. 모든 새 서비스는 템플릿에서 생성되므로, 표준 src, test, docs, deploy, scripts 폴더, 채워진 README, .editorconfig, 무시 파일, 동작하는 CI 파이프라인을 갖추고 도착합니다. 모든 저장소가 똑같이 보이므로 새 팀으로 재배치된 엔지니어는 몇 시간 안에 생산적이 되고, 조직 전체의 보안 및 의존성 스캐너는 항상 파일이 기대하는 곳에 있어서 획일적으로 실행됩니다.

정부. 레거시 시스템을 현대화하는 한 국가 기관이 모든 벤더에 대한 전달 표준의 일부로 공통 저장소 배치를 의무화합니다. 각 저장소는 코드를 승인된 요구사항에 연결하는 specification 폴더, 문서화된 README, 루트의 라이선스와 보안 정책 파일, 코드형 인프라 정의(8.2장)를 담은 deploy 폴더를 포함해야 합니다. 서로 다른 벤더의 계약자가 모두 같은 구조를 따르므로 기관의 감사자는 모든 시스템에서 컴플라이언스 산출물을 같은 방식으로 찾을 수 있고, 들어오는 유지보수자가 이미 지도를 알고 있어서 계약이 끝난 뒤의 장기 유지보수 비용이 훨씬 적습니다.

비즈니스 사례: 동기, ROI, TCO

구조 표준을 도입하는 비용은 대부분 일회성입니다. 배치에 합의하고, 템플릿을 만들고, 관례를 문서화합니다. 반복 비용은 낮고 템플릿을 유지하고 예외를 다스리는 데 집중됩니다. 표준이 없는 비용은 반복적이고 누적됩니다. 낯선 저장소를 여는 모든 엔지니어가 탐색 세금을 치르고, 모든 온보딩이 더 느려지고, 아무것도 기대하는 곳에 없어서 자동화 도구를 저장소별로 설정해야 합니다. 큰 조직 전반에서 이런 작은 마찰은 곱해져 엔지니어링 시간의 심각한 손실이 됩니다.

수익은 더 빠른 온보딩, 더 싼 팀 간 이동성, 포트폴리오 전체 도구의 더 높은 신호, 규제 환경에서는 산출물이 항상 찾을 수 있어서 더 낮은 감사 및 장기 유지보수 비용으로 나타납니다. 총소유비용(TCO, 시스템을 만들고, 운영하고, 유지하는 전체 수명 비용)은 예측 가능한 구조의 덕을 보는 유지보수자가 보통 그것을 만든 작성자가 아닌 오래 사는 시스템에서 가장 많이 떨어집니다. 리더십을 설득하려면 구조를 개발자 생산성과 감사 준비를 개선하는 저비용 고지렛대 표준으로 설명하고, 온보딩 시간 데이터와 낯선 저장소에서 물건을 찾는 데 쓰인 노력으로 오늘의 비일관성 비용에 숫자를 매기십시오.

안티패턴과 함정

  • 눈송이 저장소: 모든 저장소가 다르게 조직되어 각각을 처음부터 다시 배워야 하는 것.
  • 없거나 낡은 README: 앞문이 없어 신입이 프로젝트를 어떻게 빌드하고 실행하는지 역공학하게 하는 것.
  • 템플릿이 아닌 문서에 의한 구조: 위키 페이지가 표준 배치를 기술하지만 아무것도 그것을 생성하거나 시행하지 않아 현실이 표준에서 표류하는 것.
  • 템플릿 표류: 템플릿에서 생성된 저장소가 시간이 지나며 갈라지고 템플릿의 개선이 그들에게 닿지 않는 것.
  • 과설계된 계층: 탐색을 돕지 않고 의식만 더하는 거의 빈 폴더의 깊은 중첩.
  • 뒤섞인 관심사: 소스, 테스트, 빌드 출력, 비밀이 분명한 분리 없이 뒤죽박죽인 것.
  • 커밋된 빌드 출력과 로컬 산출물: 무시 규칙이 설정되지 않아 체크인된 생성 파일이 이력과 차이를 오염시키는 것.
  • 평평한 구조에 가려진 계층 위반: 물리적 경계가 없어 의존성 순환과 부적절한 결합이 눈에 띄지 않게 스며드는 것.

성숙도 모델

  • 1단계(시작): 각 저장소가 작성자에 의해 그때그때 필요에 반응해 조직됩니다. 배치가 크게 다르고, README는 없거나 믿을 수 없으며, 신입은 모든 저장소를 손으로 안내받아야 합니다.
  • 2단계(발전): 기본 관례가 비공식적으로 존재하고 많은 저장소가 서로 닮았으며, 일부 팀은 자기 시작 배치를 유지하지만, 권위 있는 표준도 공유 스캐폴딩도 없고 구조는 팀마다 눈에 띄게 표류합니다.
  • 3단계(표준화): 문서화되고 버전 관리되는 구조 표준이 조직 전체에서 시행됩니다. 새 저장소는 표준 배치, README, 설정 파일, CI를 지닌 공유 템플릿에서 생성되며, 일탈은 조용히 일어나지 않고 문서화된 예외 절차를 거칩니다.
  • 4단계(관리): 표준에 대한 준수가 데이터로 측정되고 통제됩니다. 자동 검사가 얼마나 많은 저장소가 배치와 일치하는지, 템플릿으로 만든 저장소가 얼마나 표류했는지, README 완전성, 의존 방향 위반을 보고하며, 모두 기준선에 대해 추적됩니다. 온보딩과 탐색 시간이 측정되고, 예외가 기록되고 검토되며, 템플릿 변경은 의견이 아닌 증거에 따라 승인됩니다.
  • 5단계(오케스트레이션): 구조가 지속적으로 개선되고 적응적입니다. 템플릿 개선이 기존 저장소에 자동으로 전파되고, 구조 거버넌스가 보안, 컴플라이언스, 플랫폼 도구와 통합되며, 표준은 언어, 아키텍처, 포트폴리오가 이동함에 따라 의도적으로 진화하여 조직이 주변에서 변하는 동안 획일성을 높게 유지합니다.

논의를 위한 아이디어

  • 조직 전체에서 진정 보편적이어야 하는 최상위 폴더는 무엇이고, 선택적이어야 하는 것은 무엇입니까?
  • 템플릿에서 생성된 저장소가 시간이 지나며 템플릿에서 표류하지 않게 하려면 어떻게 합니까?
  • 도움이 되는 계층 구조와 과설계된 폴더 의식 사이의 선은 어디에 있습니까?
  • 모노레포와 멀티 레포 접근 사이에 구조 표준이 달라야 합니까, 그렇다면 어떻게 달라야 합니까?
  • 진정한 필요가 표준 배치에 맞지 않는 프로젝트를 위한 알맞은 예외 절차는 무엇입니까?
  • 구조의 얼마나 많은 부분을 자동으로 검사할 수 있으며, 무엇이 여전히 사람의 리뷰에 의존합니까?
  • 구조 표준과 템플릿은 누가 소유하며, 변경은 어떻게 제안되고 배포됩니까?

핵심 요점

  • 최소 놀람의 원칙을 따라, 어떤 엔지니어든 기대만으로 어떤 코드베이스든 탐색할 수 있도록 모든 저장소를 조직하십시오.
  • 일관된 최상위 배치(소스, 테스트, 문서, 빌드, 배포, 스크립트, 예제, 명세)를 채택하고 README를 진입점으로 만드십시오.
  • 편집기와 도구 설정(.editorconfig 등)을 체크인해 관례가 단지 적혀 있는 것이 아니라 활성화되게 하십시오.
  • 스캐폴딩과 템플릿으로 구조를 시행해 새 저장소가 기본적으로 올바르게 하십시오.
  • 규모에서 가치는 획일성에 있습니다. 표준을 다스리고, 표류를 관리하고, 문서화된 예외로만 일탈을 허용하십시오.

참고 문헌과 더 읽을거리

  • Robert C. Martin, Clean Architecture: A Craftsman’s Guide to Software Structure and Design
  • Steve McConnell, Code Complete: A Practical Handbook of Software Construction
  • Andrew Hunt and David Thomas, The Pragmatic Programmer
  • Titus Winters, Tom Manshreck, and Hyrum Wright (eds.), Software Engineering at Google
  • Scott Chacon and Ben Straub, Pro Git
  • EditorConfig project documentation (as a reference standard for editor configuration)