- 내부 코드베이스를 관리하는 규칙
- 소스파일을 저장하는 위치
- 코드 포매팅
- 명명 방식
- 패턴
- 예외와 스레드 사용법
- 규칙은 곧 법이다. 승인된 경우를 제외하고는 무시할 수 없다.
- 지침은 권장사항과 모범 사례를 말한다. 따르는 편이 이득이지만 규칙과 달리 변형해 적용해도 괜찮다.
- 구글 스타일 가이드
- 규칙을 관리하는 목표는 좋은 행동을 장려하고 나쁜 행동을 억제하기 위함이다.
- 좋고 나쁨의 기준은 조직별로 다르다. 메모리 사용량 저감, 런타임 성능 향상, 최신 언어 기능 사용 등. 일관성을 최우선으로 하는 조직은 기존 패턴과 다른 모든 것을 나쁘다라고 표현할 수도 있다.
- 확립된 규칙과 지침은 조직이 커지더라도 일관되게 통용되는 공통의 코딩 어휘가 되어준다.
- 어휘가 통일되면 엔지니어들은 코드를 표현하는 형식보다 코드에 담을 내용에 집중할 수 있다.
왜 이 내용이 스타일 가이드에 들어가야 하지?
- 규칙 모음을 정의할 때 던져야할 질문은 '어떤 규칙이 필요하지?'가 아니라 '어떤 목표를 이루려 하지?'
- 코딩을 규제하는 규칙 모음을 만들어서 조직이 얻는 것은 무엇일까?
- 구글의 규칙 모음 가치: 규모와 시간 양쪽 측면에서 탄력적인 엔지니어링 환경이 지속되도록 하는 것
- 개발 환경의 복잡도를 관리하고 엔지니어들의 생산성을 희생하지 않는 선에서 코드베이스를 관리 가능하게끔 유지하는 것
- 엔지니어의 자유를 제한하지만 표준은 일관성을 높여주고 의견 대립을 줄여주므로 혜택이 더 크다.
- 규칙을 만들 때 염두에 두어야 하는 중요한 원칙
- 규칙의 양을 최소화한다.
- 코드를 읽는 사람에게 맞춘다.
- 일관되어야 한다.
- 오류가 나기 쉽거나 예상치 못한 동작을 유발하는 구조를 피한다.
- 꼭 필요하다면 실용성을 생각해 예외를 허용한다.
- 조직 내 모든 엔지니어가 새로운 규칙들을 익히고 적응하는 데는 비용이 든다.
- 규칙이 너무 많다면 엔지니어들이 다 기억하지도 못할 것이고 새로 합류한 엔지니어가 적응하기도 어렵다.
- 구글은 너무 자명한 규칙은 의도적으로 배제한다.
- 한두 엔지니어만의 잘못 때문에 새로운 규칙을 만들어버리면 다른 사람들에게 정신적 부담을 주게 된다. 그러면 조직 규모를 확장할 수 없다.
- 코드는 작성되는 횟수보다 읽히는 횟수가 더 많으며 시간이 지날수록 차이가 벌어진다. 그러니 읽기 난해한 것보다 타이핑하기 지루한 편이 낫다.
- 구글은 엔지니어가 의도한 행위를 분명하게 알려주는 증거를 코드에 남기라고 요구한다. 코드가 하려는 일이 무엇인지를 읽는 사람이 즉시 알 수 있기를 원하는 것.
- 설계 의도를 소스 코드에 명시하지 않으면 읽는 사람이 파악해내야 해서 그 코드를 활용해야 하는 모든 이에게 추가적인 부담을 떠안긴다.
- 행위가 헷갈리거나 오해할 수 있는 상황에서는 의도한 행위를 알려주는 근거가 더욱 중요해진다.
- 함수의 구현부를 들여다보지 않고도 호출 지점에서 무슨 일이 벌어지는지를 명확히 이해할 수 있도록 한다.
- 문서화 주석은 뒤따르는 코드의 설계나 의도를 설명한다.
- 구현 주석(코드 자체에 산재하는 주석)은 뻔하지 않은 선택을 한 이유나 해명하거나 주의할 점을 알려주고, 까다로운 부분의 로직을 설명하고, 중요한 부분을 강조한다.
- 코드가 일관되게 작성되어 있다면 엔지니어들은 익숙지 않은 부분을 살펴볼 일이 생겨도 상당히 빠르게 작업을 이어갈 수 있다.
- 로컬 프로젝트라면 고유한 개성이 허용되지만, 그 프로젝트에서 사용하는 도구, 기법, 라이브러리는 모두 똑같다.
- 일관성이 주는 이점은 우리가 잃게 되는 자유의 가치보다 훨씬 크다.
- 때로는 일관성이 구속처럼 느껴지기도 한다. 하지만 더 많은 엔지니어가 더 많은 일을 적은 노력으로 수행할 수 있게 된다.
- 모든 사람이 각자의 방식으로 코드를 작성한다면 균일성에 의존하는 도구의 이점을 제대로 누릴 수 없다. 예를 들어 누락된 임포트문을 추가하거나 쓰이지 않는 임포트문을 제거하는 도구가 있더라도 프로젝트마다 임포트문 정렬 방식이 다르다면 제대로 작동하지 않는 프로젝트가 생길 수 있다.
- 모든 사람들이 참여하는 코드를 가능한 한 일관성 있게 관리하면 엔지니어들이 새로운 팀으로 옮겨 적응하는 시간이 단축된다. 그 결과 조직의 필요에 맞게 인력을 우연하게 재배치할 수 있는 역량이 커진다.
- 시간이 흐르면서 엔지니어 일부가 프로젝트를 떠나고 새로운 인력이 합류한다. 코드 소유권이 옮겨가고 프로젝트가 합쳐지거나 나뉜다. 코드베이스가 일관되도록 노력하면 이러한 전환 비용이 낮아지고 코드와 엔지니어 모두 거의 제약 없이 재배치될 수 있다. 결국 장기적으로 봤을 때 유지보수 프로세스가 간소화된다.
- 시간이 지나면 완벽한 일관성을 추구하기에는 얻는 것보다 비용이 큰 단계에 도달할 수 있다. 언젠가는 디커플링 될 수 있음.
- '일관되게 하라'를 지켜야 하는 범위는 작게 시작해서 점차 확장된다. 파일 하나에서의 일관성이 팀의 규약보다 우선하며, 팀의 규약이 프로젝트보다, 나아가 전체 코드베이스보다 우선한다.
- 조직 내 규약을 만들어 고수하는 것만으로는 충분하지 않을 때가 있다. 때로는 외부 커뮤니티에서 정착된 표준도 고려해야 한다.
- 일반적으로 규약은 바깥세상과 일관되게 잡는 편이 유리하다.
- 수명이 길고 확장될 가능성이 큰 코드라면 언젠가 외부 코드와 상호작용하고 심지어 바깥세상으로 나가 생을 마감할 수도 있다. 그래서 길게 보면 널리 쓰이는 표준을 따르는 게 유리하다.
- 구글은 예상과 다르게 동작할 여지가 있거나 정확한 동작을 예측하기 까다로운 구조는 사용하지 않도록 제한한다.
- 복잡한 기능을 정확하게 이해하지 못한 채 사용하면 그 복잡성 때문에 오용하여 버그를 유발하기 쉽다.
- 심지어 정확히 이해하고 사용했다고 해도 나중에 합류한 팀원이나 유지보술르 맡은 엔지니어도 같은 수준으로 이해할지는 보장할 수 없다.
- 구글은 코드베이스가 특정 전문가의 전유물이 아닌 모든 엔지니어의 작업 공간이 되길 원한다. 초보 소프트웨어 엔지니어를 위한 것이기도 하지만 사이트 신뢰성 엔지니어(SRE)에게도 유리하다.
어리석게 일관성만 고집한다면 편협한 홉고블린과 다를 바 없습니다.
- 꼭 필요하다면 최적화나 실용성을 위해 예외를 허용한다.
- 성능. 일관성과 가독성을 희생해서라도 성능을 끌어올려야 할 때는 예외를 허용한다.
- 상호운용성. 구글이 만들지 않은 외부 코드와 연동되도록 설계된 코드는 대상 코드와 잘 어우러지게 작성해야 더 효율적일 수 있다.
- 빌드 과정에서 자동 생성된 코드는 가이드의 규칙을 적용받지 않는다. 프로젝트의 통제권 밖에 있는 외부 컴포넌트와 자주 인터페이스하거나 의존하기 때문이다.
- 일관성은 매우 중요하지만 융통성이 없어서는 안 된다.
- 모든 가이드 규칙은 세 범주로 나눌 수 있다.
- 위험을 피하기 위한 규칙
- 모범 사례를 적용하기 위한 규칙
- 일관성을 보장하기 위한 규칙
- 기본적으로 구글의 스타일 가이드에는 기술적인 이유 때문에 반드시 써야 하거나 쓰면 안 되는 언어 특성들에 대한 규칙들이 담겨 있다.
- 가이드에 담긴 판단 각각에는 결론에 이르기까지 고려한 장점과 단점, 그리고 어디에 무게를 두었는지도 설명되어 있다.
- 결정의 대부분은 세월이 흘러도 관리 가능한 코드를 작성하는 데 우선순위를 두어 내려졌다.
- 모범 사례를 반드시 따르도록 강제하는 규칙도 담겨 있다.
- 코드 작성자가 주석을 어디에 어떻게 작성해야하는가를 설명한다.
- 주석 관련 규칙들은 주석을 작성하는 일반적인 규약을 다루며, 코드 안에 설명을 반드시 남겨야 하는 상황도 알려준다.
- 작성자의 의도가 코드 자체에 명확하게 드러나지 않는 경우
- switch문에서의 fall-through, 빈 catch 블록, 템플릿 메타프로그래밍 등
- 콘텐츠가 읽는 사람이 기대하는 순서로 배치되도록 하기 위해 소스 파일의 구조도 규칙으로 상세하게 정의한다.
- 패키지, 클래스, 함수, 변수 등의 이름을 짓는 규칙도 있다.
- 이 규칙들의 목적은 모두 엔지니어가 보다 건실하고 지속 가능한 코드를 생산하는 습관을 몸에 익히도록 하는 것.
- 가독성 개선을 위한 모범 사례도 있다.
- 수직과 수평 공백 사용
- 한 줄의 최대 길이와 괄호 정렬 방식
- 언어에 따라 자동 포매팅 도구를 사용하게도 한다.
- 구글 스타일 가이드는 새롭거나 아직 널리 이해되지 못한 언어 기능을 제한하기도 한다. 엔지니어 전반이 해당 기능을 제대로 습득할 때까지 선제적으로 방어선을 치는 것.
- 구글 스타일 가이드에는 사소한 문제를 다루는 규칙도 아주 많다. 이 규칙들의 목적은 단순히 결정을 내리고 그 결정을 문서로 남기는 것.
- 사소함의 법칙(law of triviality)에서 벗어날 수 있다.
- 우리가 무엇을 선택했냐가 아니라 선택을 했다는 사실에 의의가 있다.
- 너무 똑똑하게 짜지 말자, 코드베이스를 포크하지 말자, 바퀴를 다시 발명하지 말자같은 기본적인 엔지니어링 조언들은 포함하지 않았다.
- 구글 스타일 가이드 같은 문서만으로 초심자를 소프트웨어 엔지니어링 숙련자 수준까지 끌어올릴 수는 없다. 그래서 일부러 모든 것을 넣지 않았다.
- 구글의 스타일 가이드는 고정불변이 아니다.
- 세월이 흐르면 기존 결정이 내려질 당시와는 내부 사정이 달라지고 결정에 영향을 준 요인들도 변할 수 있다.
- 모든 규칙을 유용하고 최신 상태로 유지하려면 업데이트가 필요한 규칙이 무엇인지를 적시에 알아챌 수 있어야 한다.
- 각 결정에 이른 근거를 문서로 남겨두면 규칙을 변경해야 할 때가 언제인지를 알아내기 쉬워진다는 이점이 있다.
- 결정에 영향을 준 요인들이 명확하게 기록되어 있다면 그 요인들 중 하나 이상이 변했는지 여부가 바로 규칙을 다시 평가해야 한다는 신호가 되어 준다.
- 먼저 현재 문제를 찾아내 설명한 다음 해법을 보여준다.
- 이 프로세스에서 말하는 문제는 잠재적인 가능성을 이야기하는 가상의 예가 아니다. 현존하는 구글 코드에서 발견된 패턴으로 입증해야 한다.
- 규칙이 수정되어야 할 시점을 알아차리는 것은 엔지니어 커뮤니티를 참고한다.
- 커뮤니티의 검토를 거친 제안은 최종 승인 단계로 넘어간다.
- 구글의 스타일 가이드들은 언어별로 소유자가 따로 있어서 최종 결정과 승인을 책임진다.
- 프로그래밍 언어별로 경험 많은 전문가 그룹이 스타일 가이드를 소유하고 결정권자 역할을 한다.
- 스타일 가이드 수정 여부는 제안된 수정에 따르는 엔지니어링 측면의 트레이드오프를 논의하여 결정하며, 중재자는 스타일 가이드가 지향하는 목표에 입각하여 판단한다.
- 스타일 가이드의 규칙은 법과 같지만 일부 규칙은 예외를 허용한다.
- 규칙을 따르기보다 예외를 인정하는 쪽이 이득이라고 판단될 때만 예외를 허용한다.
- 구글의 엔지니어링 경험에서 선별한 지혜이자 과거로부터 배운 교훈들로부터 추린 모범 사례들을 문서로 남긴 것.
- 주로 사람들이 자주 실수하는 것 혹은 아직 익숙지 않은 새로운 주제라서 혼란스러워하는 것들에 집중한다.
- 규칙이 반드시(must) 지켜야 하는 것이라면 지침은 되도록(should) 따라야 하는 것이다.
- 입문서(primer)는 가이드가 권장하는 기능을 상세하게 설명한다. 다루는 범위가 매우 넓어 해당 언어를 처음 접하는 엔지니어가 구글에서 개발하는 데 참고해야 할 거의 모든 주제를 다룬다.
- 구글이 내부적으로 관리하는 유용한 참고자료 예시
- 올바로 구현하기 어려운 주제에 대한 언어별 조언(예: 동시성과 해싱)
- 언어의 최신 버전에서 소개된 새로운 기능의 상세 설명과 구글 코드베이스에 적용하는 방법에 대한 조언
- 구글 라이브러리가 제공하는 중요한 추상 개념과 데이터 구조 목록. 이미 만들어둔 구조를 새로 만드는 일을 방지해주고 '필요한 게 있는데 우리 라이브러리에서 이걸 뭐라고 부르는지 모르겠어'와 같은 질문에 답해준다.
- 규칙을 정해도 적용하지 않으면 의미가 없다.
- 규칙을 강제하는 방법은 교육과 훈련을 통한 사회적 방법과 도구를 이용한 기술적인 방법이 있다.
- 규칙이 실제로 지켜지는지 확인하는 데는 사람보다는 되도록 자동화 도구를 활용한다.
- 도구를 활용하면 규칙을 미묘하게 다르게 해석하거나 적용하는 일을 최소한으로 줄여준다.
- 기술보다는 사회적 문제를 다루는 규칙도 있으며 사회적 문제를 기술적 시각으로 해결하려 드는 것은 현명하지 않다.
- 언어 사용법과 관련된 규칙들의 상당수는 정적 분석 도구로 강제할 수 있다.
- 코드의 형식을 일관되게 관리하기 위해 자동 스타일 검사기와 포맷터를 적극 이용한다.
- 모든 조직에는, 특히 구글의 엔지니어링 조직처럼 큰 조직이라면 코드베이스의 복잡성을 관리하여 감당할 수 있는 수준으로 유지하는 데 규칙이 큰 도움이 된다.
- 모두가 함께 사용하는 규칙 모음은 엔지니어링 프로세스에 기준을 잡아두어 코드베이스를 계속 확장하고 성장할 수 있게 해준다.
- 그 결과 코드베이스와 조직 모두 오랜 기간 살아 숨 쉴 수 있게 된다.
- 규칙과 지침의 목표는 시간과 확장 관점에서의 탄력성을 높이는 것이어야 한다.
- 상황이 변하면 규칙도 달라져야 하니 규칙이 만들어진 근거 데이터를 알고 있어야 한다.
- 모든 것을 규칙으로 강제해서는 안 된다.
- 일관성이 핵심이다.
- 가능한 한 규칙들이 자동으로 적용되도록 해야 한다.