Back-End/Golang
golang: 고언어의 철학(Clear is better than clever)
슝슝이입니다
2024. 11. 16. 22:17
반응형
"Clear is better than clever"("명확성은 영리함보다 우수하다)는 Go 언어의 설계 철학 중 하나로, 코드의 가독성과 명확성을 우선시해야 한다는 원칙을 뜻합니다. 이는 Go 언어 설계자들이 Go 언어의 단순하고 직관적인 사용성을 강조하면서, 복잡하거나 지나치게 "영리한" 코드 작성을 피하자는 철학입니다.
세부 설명
- Clear (명확성):
- 코드를 읽는 사람이 쉽게 이해할 수 있는 코드를 작성하는 것을 지향합니다.
- 코드가 직관적이어야 팀원이나 후임자가 코드를 읽고 수정하거나 유지보수하기 쉽습니다.
- "이 코드는 무엇을 하는지 바로 알 수 있는가?"를 기준으로 작성.
- Clever (영리함):
- 지나치게 복잡하거나 고도의 기술적인 구현(트릭)을 사용한 코드.
- 한 번에 많은 일을 처리하거나, 너무 축약된 표현으로 인해 읽기 어려운 코드.
- "이 코드는 왜 이렇게 동작하지?"라는 의문이 드는 코드.
의미 있는 코드 예제
1. "Clear is better than clever"를 따른 코드
명확한 코드 (Clear)
// 배열에서 짝수만 필터링
func filterEvens(numbers []int) []int {
var evens []int
for _, n := range numbers {
if n%2 == 0 {
evens = append(evens, n)
}
}
return evens
}
- 특징:
- 누구나 이 코드를 보면, "짝수를 필터링하는 코드"라는 것을 바로 이해할 수 있음.
- 비록 다소 코드가 길어 보일 수 있어도, 가독성이 높고 유지보수가 용이.
2. 지나치게 영리한 코드 (Clever)
// 배열에서 짝수만 필터링 (영리한 방식)
func filterEvens(numbers []int) []int {
return filter(numbers, func(n int) bool { return n%2 == 0 })
}
func filter(numbers []int, predicate func(int) bool) []int {
var result []int
for _, n := range numbers {
if predicate(n) {
result = append(result, n)
}
}
return result
}
- 문제점:
- 함수형 프로그래밍 스타일처럼 보이지만, filter라는 추상화된 함수와 predicate 콜백이 등장하면서 코드를 이해하는 데 추가적인 학습 비용이 필요.
- 작은 기능을 구현하는 데 과도한 추상화와 복잡성이 추가됨.
왜 "Clear is better than clever"가 중요한가?
- 가독성:
- 명확한 코드는 팀원들이 더 빠르게 이해할 수 있습니다.
- 복잡한 로직이나 축약된 표현은 시간이 지나면 작성자조차 이해하기 어려울 수 있습니다.
- 유지보수성:
- 명확한 코드는 변경이나 확장이 필요할 때 문제가 덜 발생합니다.
- 지나치게 영리한 코드는 버그가 생기기 쉽고 수정 시 의도하지 않은 문제를 유발할 가능성이 높습니다.
- 협업:
- 팀 작업에서는 코드의 명확성이 특히 중요합니다.
- 다양한 경험 수준의 개발자들이 코드베이스를 공유할 때, 명확한 코드가 더 효과적입니다.
- Go 언어 철학:
- Go는 언어 자체가 단순성과 명확성을 지향하도록 설계되었습니다.
- 복잡한 메타프로그래밍(예: 매크로, 제네릭 과도 사용)을 피하고, 직관적인 코드 작성을 권장합니다.
"Clear"와 "Clever"의 현실적인 적용
명확성의 좋은 예
- 변수 이름을 직관적으로 작성.
- 간단한 루프나 조건문을 사용하는 것을 우선.
- 한 번에 하나의 작업만 수행.
// 평균 구하기
func average(numbers []int) float64 {
if len(numbers) == 0 {
return 0
}
sum := 0
for _, n := range numbers {
sum += n
}
return float64(sum) / float64(len(numbers))
}
지나치게 영리한 구현
- 한 줄로 모든 로직을 처리하려는 시도.
- 축약된 구문이나 과도한 추상화를 남용.
// 평균 구하기 (영리한 구현)
func average(numbers []int) float64 {
return float64(sum(numbers)) / float64(len(numbers))
}
func sum(numbers []int) int {
return reduce(numbers, 0, func(a, b int) int { return a + b })
}
func reduce(numbers []int, initial int, fn func(int, int) int) int {
result := initial
for _, n := range numbers {
result = fn(result, n)
}
return result
}
- 문제점: reduce와 같은 추상화는 단순한 기능을 과도하게 복잡하게 만들며, 가독성을 해칩니다.
결론
- "Clear is better than clever"는 협업과 유지보수성을 강조합니다.
- 코드 작성 시, "나 자신이 아닌 다른 개발자가 쉽게 이해할 수 있을까?"라는 질문을 던지세요.
- Go의 설계 철학과 일치:
- Go는 복잡함을 배제하고 직관적인 코드 작성을 지향합니다.
- 이 원칙은 코드 작성뿐 아니라 Go 언어 자체의 심플한 문법과 표준 라이브러리에도 반영되어 있습니다.
- 언제나 명확성이 우선:
- 영리한 코드가 필요할 때도 있지만, 대부분의 경우 명확한 코드가 더 큰 가치를 제공합니다.
반응형