Basic

44. Back-end : 좋은 네이밍의 습관 10 (네이밍 컨벤션)

천재단미 2025. 1. 3. 00:49
728x90
반응형

 

 

 
 

 
네이밍 컨벤션 
 
Quora 및 Ubuntu 포럼에서 진행된 토론 스레드에 따르면 토론에 응답한 개발자 49%가 이름 짓는 걸 가장 어려운 작업으로 답했습니다.
 
네이밍 컨벤션은 코드에서 변수, 함수 등의 이름을 짓는 일관된 규칙을 말합니다. 네이밍컨벤션은 코드의 가독성을 높이고 협업 시 통일성을 유지하기 위해 사용합니다.

 

네이밍 컨벤션의 중요성 및 장점

  1. 코드 가독성 향상: 명확한 네이밍 규칙을 따르면, 누구나 코드를 쉽게 이해할 수 있습니다. 변수가 무엇을 나타내는지, 함수가 어떤 역할을 하는지 직관적으로 파악할 수 있습니다.
  2. 유지보수 용이: 이름이 잘 정의된 코드는 코드 수정이 간편합니다. 시간이 지나도 코드의 의미를 잊지 않고 파악이 가능하며, 다른 개발자가 코드를 이어받았을 때도 이해가 쉽습니다.
  3. 협업 효율성 증가: 여러 개발자가 협업할 때, 동일한 네이밍 규칙을 사용하면 코드 스타일이 일관되게 유지되어 충돌이나 혼동이 줄어듭니다.
  4. 디버깅 및 테스트 용이성: 의미 있는 이름을 사용하면 버그를 찾거나 테스트할 때도 정확히 어떤 부분을 수정해야 하는지 파악하기 쉬워집니다.

대표적인 네이밍 컨벤션

카멜 케이스 (camelCase)

  • 첫 단어를 제외한 각 단어가 낙타의 혹처럼 보여 카멜 케이스
  • 소문자로 시작하며, 이후 각 단어의 첫 글자를 대문자로 작성하는 방식
  • 주로 변수명과 함수명에 사용
  • 예시: myVariableName, getUserData, phoneNumber
파스칼 케이스 (PascalCase)
  • 모든 단어의 첫 글자를 대문자로 작성
  • 주로 클래스명이나 생성자 함수명에 사용
  • 예시: MyClassName, FetchUserData, ShoppingCart

스네이크 케이스 (snake_case)

  • 단어를 연결하는 언더스코어가 뱀의 몸처럼 보여 스네이크 케이스
  • 모든 철자를 소문자로 작성하고 단어 사이에 언더스코어(_)을 사용하여 연결
  • 주로 상수명이나 파일명에 사용
  • 예시: user_id, phone_number

케밥 케이스 (kebab-case)

  • 연결된 단어가 꼬챙이에 꿴 케밥처럼 보여 케밥 케이스
  • 모든 철자를 소문자로 작성하고 단어 사이를 하이픈(-)으로 연결
  • 주로 URL 경로나 CSS 클래스명에 사용
  • 예시: max-width, fetch-user-data

그 외에도 플랫 케이스(Flat Case), 헝가리안 표기법(Hungarian Notation) 등 있습니다.

네이밍 컨벤션을 잘 따르는 방법

  • 의미 있는 이름 사용: 변수나 함수의 목적을 명확하게 알 수 있는 이름을 짓는 것이 중요합니다. count라는 변수 보다 userCount처럼 구체적으로 짓는 것이 좋습니다.
  • 일관성 유지: 프로젝트 전체에서 다른 개발자들과 동일한 네이밍 규칙을 유지해야 합니다.
  • 적절한 길이: 너무 짧은 네이밍은 의미를 잃고, 너무 긴 네이밍은 가독성을 해칠 수 있습니다. 적절한 길이를 유지해야 합니다.

여러 네이밍 컨벤션 유형을 따르기에 앞서, 어떤 단어로 이름을 지을 것인지도 매우 중요합니다. 네이밍 컨벤션의 핵심은 정확한 의미를 알기 쉽게 입니다.
 
한가지 예시를 보여드리겠습니다. 
코틀린 컨벤션 문서에서는 아래와 같은 순서로 클래스 내부 코드를 배치하도록 권고합니다.

 
class 
    프로퍼티 선언
    
    init 블록
    
    부 생성자
    
    메소드 선언
    
    companion object

 
아래 lazy 프로퍼티를 가지는 클래스를 보면,

class LazyInitializationExample {
    
    val lazyProperty: String by lazy {
        println("Lazy property initialized")
        "Initialized Lazy Property"
    }
    
    init {
        println("Init block executed")
        println("Accessing lazy property inside init block: ${lazyProperty}")
    }        
}

fun main() {
    val example = LazyInitializationExample() // 객체 생성
}

 
이는 정상적으로 작동하는 것을 알 수 있습니다. 
 

출력
Init block executed
Lazy property initialized
Accessing lazy property inside init block: Initialized Lazy Property

 
그런데 만약 init 블록을 프로퍼티 위로 올리면 어떻게 될지 아래와 같이 보겠습니다. 
 

class LazyInitializationExample {
    
    init {
        println("Init block executed")
        println("Accessing lazy property inside init block: ${lazyProperty}")
    }
    
    val lazyProperty: String by lazy {
        println("Lazy property initialized")
        "Initialized Lazy Property"
    }
}
  에러 발생
Variable 'lazyProperty' must be initialized

 
코틀린의 lazy 프로퍼티는 선언되고 나서 실제로 사용되는 시점에서 초기화되는 기능입니다. 
그래서 두번째 코드에서는 에러가 발생하는 것을 볼 수 있습니다. 
이것은 고치기 어려운 에러는 아니지만, 쉽게 실수할 수도 있으며 작업의 효율성 또한 떨어질 수 있습니다. 
 
 

간단히 요약하면 

 
1. 변수, 클래스명에는 동사는 넣지 않는다.
 
클래스 FeatureExtract (❌) -> FeatureExtractor (👍)
변수 work -> worker
 
2. 함수명에는 동사를 넣는다.
id()(❌) -> getId()(👍)
trainer() (❌) -> train() (👍)
 
3. 변수명에 굳이 관사를 넣지 않는다.
 a_cat (❌) -> cat (👍)
 
4. 변수명에 전치사는 최대한 생략한다.
theNumberOfWorker (❌) -> workerCount (👍)
 
5. 단수와 복수를 구분한다.
 
6. 사용하는 언어의 코딩 컨벤션을 지킨다.
ex: [코틀린 코딩 컨벤션]
 
7. 통상적으로 사용되는 변수명/규칙을 사용한다.
 
8. 상수는 모두 대문자로 표시해준다.
const main_width = 1024 (❌) -> const MAIN_WIDTH = 1024(👍)
 
9. 로직이 끝나면 한줄 띄어준다.
 
10. 코드에 규칙이 있어야 한다.
 
위 규칙을 지키지 않더라도, 네이밍과 코드에는 일정한 규칙이 있어야 한다. 이 규칙은 팀과 협의된 규칙이어야 합니다. 
 
 
출처:
https://sh1mj1-log.tistory.com/227
https://velog.io/@eddy_song/why-naming-matters
https://yoondii.tistory.com/88
https://sooftware.io/coding-habit/
https://kotlinlang.org/docs/coding-conventions.html#class-layout
https://www.youtube.com/watch?v=VHAXJxcHA1k

728x90
반응형
home top bottom
}