요즘은 팀에서 협업 문화를 만들어가고 싶어서 이것저것 공부하고 있다.
그중 하나는 go의 style guide에 대해서 공부를 해야되겠다고 느꼈는데, effective go 말고도 구글에서 제공하는 스타일 가이드 문서가 있어서 잘 읽어보았다.
문서에는 3가지 style guide, style decision, best practice가 있는데, 일단 style guide문서부터 읽어보았다.
무엇보다 구글이 추구하는것은 읽기쉬운 코드라는걸을 새삼 느끼고간다.
왜 이코드를 사용했는지 주석을 달라는 부분도 그러한 부분을 느끼게되는 인상깊은 부분중 하나였다.
5 principle to code
golang style의 5가지 원칙
1. clarity - 명확하게 전달
2. simplicity - 간단해야 된다.
3. concision - high signal to noise - 필요한 부분만
4. maintainable - 유지보수가 쉬워야된다.
5. consistency - 코드 작성의 일관성
clarity
- naming/ 효율적인 주석/ 효율적인 코드구성이 clarity에 영향을 끼친다.
- 코드는 작성보다 읽는게 중요
읽는데 중요한 2가치 측면
- 코드가 실제로 무엇을 하고있는가?
- 코드가 수행되는 이유는?
첫번째 측면
- 코드를 처음보는 사람은 코드의 목적과 활용방안을 처음으로 생각할 것이고, 코드의 행위가 명확해야지 이해가 쉬워진다.
- 서술적인 naming
- 추가 주석
- 공백과 주석으로 코드를 분할
- 모듈화
두번째 측면
- why? 너무 중요한 주석 중 하나라고 생각됨
- 언어상의 이유
- 비지니스관점에서의 이유
- 주석은 코드에대한 동작설명보다 왜 실행해야되는지 설명하는게 좋을때가 많음
simplicity
- 사용, 읽기 유지보수가 간단해야된다.
고려해야될 사항
- 순서대로 읽기 편해야됨
- 무엇을 하는지 알고있다고 가정x
- 모든과정의 코드를 알고있다고 가정x
- 불필요한 특별한 네이밍x
- 전달하고자하는걸 독자에게 명확하게 전달
- 무엇을 수행하는지가 아닌, 왜 수행하는지에대한 주석
- 코드에 대한 문서화
- useful error & test code
- clever한 코드랑 반대될수있음, 최적화만이 좋은코드를 아님을 의미
api의 사용성과 code의 간편성은 서로 트레이드오프 가능성이있음 단순한 사용방법과 복잡한 사용방법을 제공함에 따라서 복잡한 구조를 이해할수있는 무언가를 제공해야된다.
최소한 지켜야될 사항들
- 여러가지 표현이 있을때는 표준의 방법을 선택
- 사용사례가 없을경우, 최대한 언어의 핵심적이 부분을 사용(채널, 슬라이스, 맵 등등)
- 없을경우 표준 라이브러리
- google 코드베이스에 사용하고있는 라이브러리가 있는지 확인 ex. 값을 비교하는 bool을 판별할때는 map string[bool]이면 충분한데, 값을 비교하는 패키지는 더욱 복잡한 경우에 사용해야한다.
concision
- 전달하고자하는 것만 간결하게 코드에 넣는것. signal to noise ratio
방해요소
- 반복되는 코드 - 각 코드의 의미 파악이 어려워지며, 코드간의 차이점을 일일히 찾아봐야되는 수고 (좋은 예시는 테스트 테이블을 이용한 테스트)
- 관련없는 신택스
- 불명확한 이름
- 불필요한 추상화
- whitespace
코드를 구성하는 여러가지 방식이 있을때, 코드들의 의미가 분명해지는 방식으로 구현해야된다.
if err := doSomething(); err != nil { // ... }
// Good: if err := doSomething(); err == nil { // if NO error // ... }
와같이 약간의 변화가 있을때 추가적인 주의를 줌으로 코드를 명확히 할 수 있다.
maintainablility
- 작성되는 회수보다 읽혀지는 회수가 더 많기 때문에 일기가 쉬워야된다, 그리고 그것은 유지보수에 직접적 영향을 준다.
특성
- 미래의 프로그래머가 수정하기 쉽다.
- 구조적으로 올바른 api
- problem을 구조를 추상화해라, 코드의 구조가 아닌
- 불필요한 결합x, 사용되지않는 기능x
interface/ type으로 추상화할때 이점이 명확한가 확인해야된다. 인터페이스는 강력하지만, 세부사항을 이해가 필요한 부분 코드의 이해에 load가 생김.
if user, err = db.UserByID(userID); err != nil { // ... } bad
// Good: u, err := db.UserByID(userID) if err != nil { return fmt.Errorf("invalid origin user: %s", err) } user = u
좀더 중요한 부분을 떼어내거나, 변경가능성의 여지를 열어주는 것이 중요하다.
- 핵심로직이나 엣지케이스를 helper함수로 랩핑하게된다면, 추후 수정이 될때 놓칠 가능성이 있다.
- 이름이 역할을 예측하는데 도움을 주는 이름. -> 동일한 개념을 가진 함수들은 동일한 이름을 갖도록 코딩해야된다.
- 너무 많은 종속성은 유지보수의 난이도를 향상시키다.
- 또한 유지보수성을 높이는 변경의 유연성을 증가시키는 복잡한 구조는 오히려 좋다.
consistency
- 일관성
- 유사한 코드의 형태- 코드의 파악이 매우 쉬워진다.
core guidance
- formating = go.fmt
- camelCase
- tap으로 시작줄이 바뀔때는 여러줄로 쓰지말고 한줄로 써라
- naming을 반복적이지 않고,context를 고려하고, 명확한 것을 반복x -> 추가페이지 존재
'프로그래밍 > golang' 카테고리의 다른 글
| concurrency in go(2) (0) | 2023.01.03 |
|---|---|
| concurrency in go(1) (0) | 2022.12.31 |
| golang 팀내 테스트 코드 작성 (0) | 2022.11.20 |
| golang style guide (0) | 2022.11.20 |
| aws api signature 구현 (0) | 2022.11.07 |