Skip to content

Latest commit

 

History

History
199 lines (146 loc) · 16 KB

8. Style Guides and Rules.md

File metadata and controls

199 lines (146 loc) · 16 KB

8. 스타일 가이드와 규칙

  • 내부 코드베이스를 관리하는 규칙
    • 소스파일을 저장하는 위치
    • 코드 포매팅
    • 명명 방식
    • 패턴
    • 예외와 스레드 사용법
  • 규칙은 곧 법이다. 승인된 경우를 제외하고는 무시할 수 없다.
  • 지침은 권장사항과 모범 사례를 말한다. 따르는 편이 이득이지만 규칙과 달리 변형해 적용해도 괜찮다.
  • 구글 스타일 가이드

8.1 규칙이 필요한 이유

  • 규칙을 관리하는 목표는 좋은 행동을 장려하고 나쁜 행동을 억제하기 위함이다.
  • 좋고 나쁨의 기준은 조직별로 다르다. 메모리 사용량 저감, 런타임 성능 향상, 최신 언어 기능 사용 등. 일관성을 최우선으로 하는 조직은 기존 패턴과 다른 모든 것을 나쁘다라고 표현할 수도 있다.
  • 확립된 규칙과 지침은 조직이 커지더라도 일관되게 통용되는 공통의 코딩 어휘가 되어준다.
  • 어휘가 통일되면 엔지니어들은 코드를 표현하는 형식보다 코드에 담을 내용에 집중할 수 있다.

8.2 규칙 만들기

왜 이 내용이 스타일 가이드에 들어가야 하지?

  • 규칙 모음을 정의할 때 던져야할 질문은 '어떤 규칙이 필요하지?'가 아니라 '어떤 목표를 이루려 하지?'
  • 코딩을 규제하는 규칙 모음을 만들어서 조직이 얻는 것은 무엇일까?

8.2.1 기본 원칙 안내

  • 구글의 규칙 모음 가치: 규모와 시간 양쪽 측면에서 탄력적인 엔지니어링 환경이 지속되도록 하는 것
  • 개발 환경의 복잡도를 관리하고 엔지니어들의 생산성을 희생하지 않는 선에서 코드베이스를 관리 가능하게끔 유지하는 것
  • 엔지니어의 자유를 제한하지만 표준은 일관성을 높여주고 의견 대립을 줄여주므로 혜택이 더 크다.
  • 규칙을 만들 때 염두에 두어야 하는 중요한 원칙
    • 규칙의 양을 최소화한다.
    • 코드를 읽는 사람에게 맞춘다.
    • 일관되어야 한다.
    • 오류가 나기 쉽거나 예상치 못한 동작을 유발하는 구조를 피한다.
    • 꼭 필요하다면 실용성을 생각해 예외를 허용한다.

규칙의 양을 최소화한다

  • 조직 내 모든 엔지니어가 새로운 규칙들을 익히고 적응하는 데는 비용이 든다.
  • 규칙이 너무 많다면 엔지니어들이 다 기억하지도 못할 것이고 새로 합류한 엔지니어가 적응하기도 어렵다.
  • 구글은 너무 자명한 규칙은 의도적으로 배제한다.
  • 한두 엔지니어만의 잘못 때문에 새로운 규칙을 만들어버리면 다른 사람들에게 정신적 부담을 주게 된다. 그러면 조직 규모를 확장할 수 없다.

읽는 사람에게 맞춘다

  • 코드는 작성되는 횟수보다 읽히는 횟수가 더 많으며 시간이 지날수록 차이가 벌어진다. 그러니 읽기 난해한 것보다 타이핑하기 지루한 편이 낫다.
  • 구글은 엔지니어가 의도한 행위를 분명하게 알려주는 증거를 코드에 남기라고 요구한다. 코드가 하려는 일이 무엇인지를 읽는 사람이 즉시 알 수 있기를 원하는 것.
  • 설계 의도를 소스 코드에 명시하지 않으면 읽는 사람이 파악해내야 해서 그 코드를 활용해야 하는 모든 이에게 추가적인 부담을 떠안긴다.
  • 행위가 헷갈리거나 오해할 수 있는 상황에서는 의도한 행위를 알려주는 근거가 더욱 중요해진다.
  • 함수의 구현부를 들여다보지 않고도 호출 지점에서 무슨 일이 벌어지는지를 명확히 이해할 수 있도록 한다.
  • 문서화 주석은 뒤따르는 코드의 설계나 의도를 설명한다.
  • 구현 주석(코드 자체에 산재하는 주석)은 뻔하지 않은 선택을 한 이유나 해명하거나 주의할 점을 알려주고, 까다로운 부분의 로직을 설명하고, 중요한 부분을 강조한다.

일관되어야 한다

  • 코드가 일관되게 작성되어 있다면 엔지니어들은 익숙지 않은 부분을 살펴볼 일이 생겨도 상당히 빠르게 작업을 이어갈 수 있다.
  • 로컬 프로젝트라면 고유한 개성이 허용되지만, 그 프로젝트에서 사용하는 도구, 기법, 라이브러리는 모두 똑같다.

일관성이 안겨주는 이점

  • 일관성이 주는 이점은 우리가 잃게 되는 자유의 가치보다 훨씬 크다.
  • 때로는 일관성이 구속처럼 느껴지기도 한다. 하지만 더 많은 엔지니어가 더 많은 일을 적은 노력으로 수행할 수 있게 된다.
  • 모든 사람이 각자의 방식으로 코드를 작성한다면 균일성에 의존하는 도구의 이점을 제대로 누릴 수 없다. 예를 들어 누락된 임포트문을 추가하거나 쓰이지 않는 임포트문을 제거하는 도구가 있더라도 프로젝트마다 임포트문 정렬 방식이 다르다면 제대로 작동하지 않는 프로젝트가 생길 수 있다.
  • 모든 사람들이 참여하는 코드를 가능한 한 일관성 있게 관리하면 엔지니어들이 새로운 팀으로 옮겨 적응하는 시간이 단축된다. 그 결과 조직의 필요에 맞게 인력을 우연하게 재배치할 수 있는 역량이 커진다.
  • 시간이 흐르면서 엔지니어 일부가 프로젝트를 떠나고 새로운 인력이 합류한다. 코드 소유권이 옮겨가고 프로젝트가 합쳐지거나 나뉜다. 코드베이스가 일관되도록 노력하면 이러한 전환 비용이 낮아지고 코드와 엔지니어 모두 거의 제약 없이 재배치될 수 있다. 결국 장기적으로 봤을 때 유지보수 프로세스가 간소화된다.
  • 시간이 지나면 완벽한 일관성을 추구하기에는 얻는 것보다 비용이 큰 단계에 도달할 수 있다. 언젠가는 디커플링 될 수 있음.

표준 정하기

  • '일관되게 하라'를 지켜야 하는 범위는 작게 시작해서 점차 확장된다. 파일 하나에서의 일관성이 팀의 규약보다 우선하며, 팀의 규약이 프로젝트보다, 나아가 전체 코드베이스보다 우선한다.
  • 조직 내 규약을 만들어 고수하는 것만으로는 충분하지 않을 때가 있다. 때로는 외부 커뮤니티에서 정착된 표준도 고려해야 한다.
  • 일반적으로 규약은 바깥세상과 일관되게 잡는 편이 유리하다.
  • 수명이 길고 확장될 가능성이 큰 코드라면 언젠가 외부 코드와 상호작용하고 심지어 바깥세상으로 나가 생을 마감할 수도 있다. 그래서 길게 보면 널리 쓰이는 표준을 따르는 게 유리하다.

오류를 내기 쉽거나 예상과 다르게 동작할 여지가 있는 구조는 피하자

  • 구글은 예상과 다르게 동작할 여지가 있거나 정확한 동작을 예측하기 까다로운 구조는 사용하지 않도록 제한한다.
  • 복잡한 기능을 정확하게 이해하지 못한 채 사용하면 그 복잡성 때문에 오용하여 버그를 유발하기 쉽다.
  • 심지어 정확히 이해하고 사용했다고 해도 나중에 합류한 팀원이나 유지보술르 맡은 엔지니어도 같은 수준으로 이해할지는 보장할 수 없다.
  • 구글은 코드베이스가 특정 전문가의 전유물이 아닌 모든 엔지니어의 작업 공간이 되길 원한다. 초보 소프트웨어 엔지니어를 위한 것이기도 하지만 사이트 신뢰성 엔지니어(SRE)에게도 유리하다.

실용적 측면을 인정하자

어리석게 일관성만 고집한다면 편협한 홉고블린과 다를 바 없습니다.

  • 꼭 필요하다면 최적화나 실용성을 위해 예외를 허용한다.
  • 성능. 일관성과 가독성을 희생해서라도 성능을 끌어올려야 할 때는 예외를 허용한다.
  • 상호운용성. 구글이 만들지 않은 외부 코드와 연동되도록 설계된 코드는 대상 코드와 잘 어우러지게 작성해야 더 효율적일 수 있다.
  • 빌드 과정에서 자동 생성된 코드는 가이드의 규칙을 적용받지 않는다. 프로젝트의 통제권 밖에 있는 외부 컴포넌트와 자주 인터페이스하거나 의존하기 때문이다.
  • 일관성은 매우 중요하지만 융통성이 없어서는 안 된다.

8.2.2 스타일 가이드

  • 모든 가이드 규칙은 세 범주로 나눌 수 있다.
    • 위험을 피하기 위한 규칙
    • 모범 사례를 적용하기 위한 규칙
    • 일관성을 보장하기 위한 규칙

위험 회피하기

  • 기본적으로 구글의 스타일 가이드에는 기술적인 이유 때문에 반드시 써야 하거나 쓰면 안 되는 언어 특성들에 대한 규칙들이 담겨 있다.
  • 가이드에 담긴 판단 각각에는 결론에 이르기까지 고려한 장점과 단점, 그리고 어디에 무게를 두었는지도 설명되어 있다.
  • 결정의 대부분은 세월이 흘러도 관리 가능한 코드를 작성하는 데 우선순위를 두어 내려졌다.

모범 사례 강제하기

  • 모범 사례를 반드시 따르도록 강제하는 규칙도 담겨 있다.
  • 코드 작성자가 주석을 어디에 어떻게 작성해야하는가를 설명한다.
  • 주석 관련 규칙들은 주석을 작성하는 일반적인 규약을 다루며, 코드 안에 설명을 반드시 남겨야 하는 상황도 알려준다.
    • 작성자의 의도가 코드 자체에 명확하게 드러나지 않는 경우
    • switch문에서의 fall-through, 빈 catch 블록, 템플릿 메타프로그래밍 등
  • 콘텐츠가 읽는 사람이 기대하는 순서로 배치되도록 하기 위해 소스 파일의 구조도 규칙으로 상세하게 정의한다.
  • 패키지, 클래스, 함수, 변수 등의 이름을 짓는 규칙도 있다.
  • 이 규칙들의 목적은 모두 엔지니어가 보다 건실하고 지속 가능한 코드를 생산하는 습관을 몸에 익히도록 하는 것.
  • 가독성 개선을 위한 모범 사례도 있다.
    • 수직과 수평 공백 사용
    • 한 줄의 최대 길이와 괄호 정렬 방식
  • 언어에 따라 자동 포매팅 도구를 사용하게도 한다.
  • 구글 스타일 가이드는 새롭거나 아직 널리 이해되지 못한 언어 기능을 제한하기도 한다. 엔지니어 전반이 해당 기능을 제대로 습득할 때까지 선제적으로 방어선을 치는 것.

일관성 구축하기

  • 구글 스타일 가이드에는 사소한 문제를 다루는 규칙도 아주 많다. 이 규칙들의 목적은 단순히 결정을 내리고 그 결정을 문서로 남기는 것.
  • 사소함의 법칙(law of triviality)에서 벗어날 수 있다.
  • 우리가 무엇을 선택했냐가 아니라 선택을 했다는 사실에 의의가 있다.

그 외

  • 너무 똑똑하게 짜지 말자, 코드베이스를 포크하지 말자, 바퀴를 다시 발명하지 말자같은 기본적인 엔지니어링 조언들은 포함하지 않았다.
  • 구글 스타일 가이드 같은 문서만으로 초심자를 소프트웨어 엔지니어링 숙련자 수준까지 끌어올릴 수는 없다. 그래서 일부러 모든 것을 넣지 않았다.

8.3 규칙 수정하기

  • 구글의 스타일 가이드는 고정불변이 아니다.
  • 세월이 흐르면 기존 결정이 내려질 당시와는 내부 사정이 달라지고 결정에 영향을 준 요인들도 변할 수 있다.
  • 모든 규칙을 유용하고 최신 상태로 유지하려면 업데이트가 필요한 규칙이 무엇인지를 적시에 알아챌 수 있어야 한다.
  • 각 결정에 이른 근거를 문서로 남겨두면 규칙을 변경해야 할 때가 언제인지를 알아내기 쉬워진다는 이점이 있다.
  • 결정에 영향을 준 요인들이 명확하게 기록되어 있다면 그 요인들 중 하나 이상이 변했는지 여부가 바로 규칙을 다시 평가해야 한다는 신호가 되어 준다.

8.3.1 프로세스

  • 먼저 현재 문제를 찾아내 설명한 다음 해법을 보여준다.
    • 이 프로세스에서 말하는 문제는 잠재적인 가능성을 이야기하는 가상의 예가 아니다. 현존하는 구글 코드에서 발견된 패턴으로 입증해야 한다.
  • 규칙이 수정되어야 할 시점을 알아차리는 것은 엔지니어 커뮤니티를 참고한다.
  • 커뮤니티의 검토를 거친 제안은 최종 승인 단계로 넘어간다.

8.3.2 스타일 중재자(Style arbiter)

  • 구글의 스타일 가이드들은 언어별로 소유자가 따로 있어서 최종 결정과 승인을 책임진다.
  • 프로그래밍 언어별로 경험 많은 전문가 그룹이 스타일 가이드를 소유하고 결정권자 역할을 한다.
  • 스타일 가이드 수정 여부는 제안된 수정에 따르는 엔지니어링 측면의 트레이드오프를 논의하여 결정하며, 중재자는 스타일 가이드가 지향하는 목표에 입각하여 판단한다.

8.3.3 예외

  • 스타일 가이드의 규칙은 법과 같지만 일부 규칙은 예외를 허용한다.
  • 규칙을 따르기보다 예외를 인정하는 쪽이 이득이라고 판단될 때만 예외를 허용한다.

8.4 지침

  • 구글의 엔지니어링 경험에서 선별한 지혜이자 과거로부터 배운 교훈들로부터 추린 모범 사례들을 문서로 남긴 것.
  • 주로 사람들이 자주 실수하는 것 혹은 아직 익숙지 않은 새로운 주제라서 혼란스러워하는 것들에 집중한다.
  • 규칙이 반드시(must) 지켜야 하는 것이라면 지침은 되도록(should) 따라야 하는 것이다.
  • 입문서(primer)는 가이드가 권장하는 기능을 상세하게 설명한다. 다루는 범위가 매우 넓어 해당 언어를 처음 접하는 엔지니어가 구글에서 개발하는 데 참고해야 할 거의 모든 주제를 다룬다.
  • 구글이 내부적으로 관리하는 유용한 참고자료 예시
    • 올바로 구현하기 어려운 주제에 대한 언어별 조언(예: 동시성과 해싱)
    • 언어의 최신 버전에서 소개된 새로운 기능의 상세 설명과 구글 코드베이스에 적용하는 방법에 대한 조언
    • 구글 라이브러리가 제공하는 중요한 추상 개념과 데이터 구조 목록. 이미 만들어둔 구조를 새로 만드는 일을 방지해주고 '필요한 게 있는데 우리 라이브러리에서 이걸 뭐라고 부르는지 모르겠어'와 같은 질문에 답해준다.

8.5 규칙 적용하기

  • 규칙을 정해도 적용하지 않으면 의미가 없다.
  • 규칙을 강제하는 방법은 교육과 훈련을 통한 사회적 방법과 도구를 이용한 기술적인 방법이 있다.
  • 규칙이 실제로 지켜지는지 확인하는 데는 사람보다는 되도록 자동화 도구를 활용한다.
  • 도구를 활용하면 규칙을 미묘하게 다르게 해석하거나 적용하는 일을 최소한으로 줄여준다.
  • 기술보다는 사회적 문제를 다루는 규칙도 있으며 사회적 문제를 기술적 시각으로 해결하려 드는 것은 현명하지 않다.

8.5.1 오류 검사기

  • 언어 사용법과 관련된 규칙들의 상당수는 정적 분석 도구로 강제할 수 있다.

8.5.2 코드 포맷터

  • 코드의 형식을 일관되게 관리하기 위해 자동 스타일 검사기와 포맷터를 적극 이용한다.

8.6 마치며

  • 모든 조직에는, 특히 구글의 엔지니어링 조직처럼 큰 조직이라면 코드베이스의 복잡성을 관리하여 감당할 수 있는 수준으로 유지하는 데 규칙이 큰 도움이 된다.
  • 모두가 함께 사용하는 규칙 모음은 엔지니어링 프로세스에 기준을 잡아두어 코드베이스를 계속 확장하고 성장할 수 있게 해준다.
  • 그 결과 코드베이스와 조직 모두 오랜 기간 살아 숨 쉴 수 있게 된다.

8.7 핵심 정리

  • 규칙과 지침의 목표는 시간과 확장 관점에서의 탄력성을 높이는 것이어야 한다.
  • 상황이 변하면 규칙도 달라져야 하니 규칙이 만들어진 근거 데이터를 알고 있어야 한다.
  • 모든 것을 규칙으로 강제해서는 안 된다.
  • 일관성이 핵심이다.
  • 가능한 한 규칙들이 자동으로 적용되도록 해야 한다.