프로그래밍 변수 명명법 - peulogeulaeming byeonsu myeongmyeongbeob

Naming Rule

  1. PascalCasing (파스칼 케이싱)
    ■ 클래스, 열거형, 이벤트, 메서드 등의 이름을 만들 때에는 대문자로 시작하는 변수명을 사용한다.
    ■ 복합어일 경우 중간에 시작하는 새로운 단어는 대문자로 적는다.
       예) UtilityBox, MainFrame
  2. CamelCasing (카멜 케이싱)
    ■ 메서드의 매개변수의 이름에 적용되는데 첫번째 문자는 소문자로 시작하고 복합어 일 경우 파스칼 케이싱과 동일하게 적용한다.
    ■ 동일한 이름을 가지는 두 항목을 구분하는 용도로도 사용한다.
       예) utilityBox, mainFrame
  3. GNU Naming Convention
    ■ Linux의 프로젝트들은 GNU Naming Convention이라는 형태의 명명법을 주로 사용한다.
    ■ 모두 소문자를 사용하고 복합어 사이를 ‘_‘를 사용하여 연결한다.
       예) gtk_widget_activate
  4. Hungarian notation (헝가리안 표기법)
    ■ Microsoft 의 개발자중 헝가리 사람의 프로그래머가 쓰던 변수 명명법으로 MS내부에서 따라쓰기 시작하던 것이 점차 전세계의 프로그래머들에게 널리 퍼져 이젠 프로그램 코딩시 변수 명명의 표준적인 관례가 되었다.
    ■ C#에서는 이러한 명명법을 사용하지 않고 있으며 주로 윈도우즈 프로그래밍에 사용된다.
       예) g_bTrue
    ■ 첫글자 g는 전역변수, m은 멤버변수를 의미한다. 전역이나 멤버변수의 경우에는 그 다음에 _ 를 적는다.
    ■ b는 Boolean타입을 의미하고 True가 의미있는 이름이다.
       예) nCnt
    ■ 전역이나 멤버변수가 아니므로 g_ 나 m_ 가 없다.
    ■ n과 i는 자연수를 뜻하며 i는 주로 인덱스에 사용하고, n은 카운트의 목적에 주로 사용한다.
    ■ 의미있는 이름이 길 경우에는 자음만을 사용한다.
  5. BREW Naming Convention
    ■ BREW 는 Qualcomm에서 만든 플랫폼으로 국내의 휴대폰 제조사들은 초기부터 현재까지 이 코드들을 많이 사용하고 있다.
    ■ 기존 명명법을 조합한 형태로 변종 명명법이지만, 익숙함을 벗어나지 못하는 국내 제조사의 개발자들이 선호하는 형태이다.
    ■ 클래스나 인터페이스를 대문자나 파스칼 케이싱으로 앞에 두고, ‘_‘ 이후에 다시 파스칼 케이싱 형태의 메서드 명을 적는다.
       예) IDISPLAY_ClearScreen
  6. Constant (상수)
    ■ 거의 모든 명명법에서 상수를 표기하는 방법은 거의 동일하다.
    ■ 모든 문자를 대문자로 사용하는 GNU Naming Convention의 형태를 사용한다.
       예) DEFAULT_COUNTRY_CODE
    다양한 명명법들이 존재한다. 어떤 방법이 가장 좋다라는 것은 없다. 프로젝트의 상황에 가장 적합한 명명법을 팀에서 결정하는 것이다. 프로젝트의 초기에 명명법을 결정하고 모든 개발자들이 규칙을 따라 코드를 작성하는 것이다.




프로그래밍 변수 명명법 - peulogeulaeming byeonsu myeongmyeongbeob

프로그래밍 명명 규칙(Programming Naming Conventions)

개발자들은 코딩 할 때 클래스 명, 메소드 명, 함수 명, 변수 명, 테이블 명, 컬럼 명 등의 이름을 지을 때 어떤 규칙으로 이름을 명명할지 고민하는 경우가 많습니다. 이러한 개발자들의 고민을 덜어주기 위해 이미 개발자 선배님들께서 만들어 놓은 프로그래밍 명명 규칙(관례)으로 다음과 같은 종류가 있습니다.

낙타 표기법은 단봉 낙타의 혹을 연상한다는 의미로 명명되었습니다. 각 단어의 첫 문자를 대문자로 표기하되, 이름의 첫 문자는 소문자로 작성합니다. 일반적으로 변수명이나 함수명을 Camel Case로 작성합니다.

Ex) camelCase, varialbleName, userName

쌍봉 낙타 표기법이라고도 불립니다. 각 단어의 첫 문자를 대문자로 표기하며, 이름의 첫 문자 또한 대문자로 작성합니다. 일반적으로 Class명은 Pascal Case로 작성합니다.

Ex) PascalCase, ClassName, UserName

각 단어의 사이를 언더바(_)로 구분해주는 표기법입니다. 일반적으로 데이터베이스(DB) 테이블명이나 컬럼명을 Snake Case로 작성합니다.

Ex) snake_case, table_name, user_name

케밥 표기법은 Spinal Case, Train Case, Lisp Case라고도 불립니다. 각 단어의 사이를 하이픈(-)로 구분해주는 표기법입니다. 일반적으로 HTML 태그의 id, class 속성으로 사용됩니다.

Ex) kebab-case, spinal-case, train-case

헝가리안 표기법(Hungarian Notation)

이름 앞에 변수의 타입을 접두어로 넣어주는 표기법입니다. 접두어의 종류에는 ch(char), str(string), i(int), db(double), b(boolean) 등이 있습니다.

Ex) strUserAge, iUserAge

안녕하세요.

변수의 이름을 짓는 방법은 개발자마다 본인만의 스타일이 있습니다.

이번 포스팅에서는 소프트웨어 공학 책을 보셨다면 알 수 있는 변수의 대표적인 명명 규칙(Naming Rule)에 대해서 알아보겠습니다.


1. CamelCasing(카멜 케이싱)

 첫 번째 문자는 소문자로 표기하고, 중간에 새로 시작하는 단어가 있다면 그 단어는 대문자로 표기하는 방식입니다. 변수명이 낙타의 모양과 비슷하여 카멜 케이싱이라고 이름이 붙여졌습니다.

 Ex) helloWorld

2. PascalCasing(파스칼 케이싱)

 단어의 첫 번째 문자를 대문자로 표기하는 방식입니다.

 Ex) HelloWorld

3. SnakeCasing(스네이크 케이싱)

 모든 단어를 소문자로 작성하고, 단어 사이사이에 "_"(언더바)를 넣어서 표기하는 방식입니다. 언더바가 마치 뱀 같은 모양이라 스네이크 케이싱이라 불립니다.

 Ex) hello_world 

4. KebabCasing(케밥 케이싱)

 모든 단어를 소문자로 작성하고, 단어 사이사이에 "-"(대시)를 넣어서 표기하는 방식입니다. 케밥이 꼬챙이에 꼳힌 모습과 비슷하여 케밥 케이싱이라 불립니다. 인터넷에 검색하니 그렇게 나오는데 정말 그런지는 저도 모르겠어요... ㅋㅋㅋ

Ex) hello-world

이상 프로그래밍에서 사용하는 변수 네이밍 스타일에 대해서 알아봤습니다.

JAVA 변수명 네이밍 규칙

보통 읽기 좋은 코드를 좋은 코드라고 한다. 변수, 메소드, 클래스 등의 이름이 일관성이 없고 그것의 쓰임을 분명히 나타내지 않는다면 어떨까?

코드의 유지보수가 어려워진다.

  • 이름만 보고 쓰임을 알 수 없으면, 코드를 읽고 분석해야 하는 불필요한 과정이 필요하다.
  • 좋은 이름을 지으려면 시간이 걸리지만, 좋은 이름으로 절약하는 시간이 훨씬 더 많다.

    int a = 33;
    int age = 33;

    두 변수는 모두 나이 정보를 나타내는 변수이다. aage 중 어떤 것이 더 바람직한가? age 의 경우에는 변수를 보고 바로 나이 변수임을 알 수 있다. a 가 무엇을 의미하는지 알기 위해서는 코드 분석이 반드시 필요하다.

협업자에 대한 배려가 필요하다.

  • 협업자와 함께 개발을 하는 경우에는 이름을 통해 그것이 무엇인지 나타내야 한다.
  • 그러므로 이름을 주의 깊게 살펴 더 나은 이름이 떠오르면 개선하는 것이 좋다. 그러면 (자신을 포함해) 코드를 읽는 사람이 좀 더 행복해질 것이다.

프레임워크마다 코드 컨벤션이 달라지긴 하지만, 보통 자바는 오라클의 자바 코드 컨벤션을 따른다. 이 글에서는 모든 자바 네이밍 규칙을 다루지는 않고, 변수의 네이밍에 대한 규칙을 간단히 소개해 보려고 한다.

기본적인 변수명 네이밍 컨벤션

컴파일러에서 제한하는 변수 명명 규칙

  • 대소문자는 구분되며 길이의 제한은 없다.
  • 예약어를 사용해서는 안 된다.
  • 숫자로 시작하면 안 된다.
  • 특수문자는 _$ 만 허용한다.

JE22 에서 권장하는 변수 명명 규칙

  • 변수는 첫 글자의 소문자로 시작하는 명사로 짓는다.
  • 여러 단어로 이루어진 이름인 경우 각 단어의 첫 글자를 대문자로 한다. (카멜 표기법 사용)

좋은 변수명 짓기

의도를 분명히 밝혀 이름을 짓기

  • 따로 주석이 필요하다면 의도를 분명히 드러내지 못했다는 소리다.
  • 변수 이름은 변수가 표현하고 있는 것을 완벽하고 정확하게 설명해야 한다.
  • 이름은 가능한 구체적이어야 한다. 모호하거나 하나 이상의 목적으로 사용될 수 있는 일반적인 이름은 보통 좋지 않은 이름이다.

Set<BoardSquare> findSquaresToRemove(BoardSquare s) {...}

s 라는 이름을 봤을 때 String 의 s인지, Square의 s인지 바로 알 수가 없다.

Set<BoardSquare> findSquaresToRemove(BoardSquare boardSquare) {...}

boardSquare 라고 변경함으로써 이름을 통해 적절한 의미를 나타내줄 수 있다.

협업을 염두해서 짓기

private void validateNumericPosition(String[] expressionAsArray) {
    for (int i = 0; i < expressionAsArray.length; i += 2) {
    	...
    }
}

위 코드에서 2가 의미하는게 뭘까? 다른 사람이 봤을 때 i += 2 를 통해 어떤 처리를 하는지 파악하려면 코드를 분석해야 한다.

private void validateNumericPosition(String[] expressionAsArray) {
    int numberIndex = 2;
    for (int i = 0; i < expressionAsArray.length; i += numberIndex) {
    	...
    }
}

2에 numberIndex 라는 의미 있는 변수명을 붙여주면 숫자만 걸러내기 위한 식인지 알 수 있다.

맥락을 고려해서 짓기

앞서 보았던 여러 예시에서 나타나듯이, 이름이 지나치게 짧을 경우 변수의 용도를 알기 어렵다.

  • 의도가 불분명한 짧은 이름보다는 의미있는 맥락이 있는 긴 이름이 좋다.
  • 그러나, 쓸데없이 구구절절한 이름은 오히려 독이 된다.

    public class User{
    String userName;
    int userAge;
    ...
    }

    위 코드를 보면, 클래스의 이름에서 user정보를 담고 있다는 것을 알 수 있다. 정확한 의미를 담으려는 의도는 좋지만, 굳이 멤버변수의 이름을 userName, userAge로 지을 필요가 없다.

public class User{
    String name;
    int age;
    ...
}

user를 붙이지 않아도 충분히 정보를 전달할 수 있다.

불린 변수의 네이밍

  • 전형적인 불린 변수의 이름을 사용한다. done, error, found, success, ok 성공했다는 것을 정확히 설명하는 구체적인 이름이 있다면 다른 이름으로 대체하는 것이 좋다. found, processingComplete
  • 참이나 거짓의 의미를 함축하는 불린 변수의 이름을 사용한다. status, sourceFile 같은 변수들은 참이나 거짓이 명백하지 않으므로 좋지 못한 이름이다. statusOK, sourceFileAvailable 또는 sourceFileFound 와 같은 이름으로 대체한다.
  • 긍정적인 불린 변수 이름을 사용한다.

아래 코드에서 어떤 경우가 더 읽기 쉬운가?

if(notFound == false) {...}
if(found == true) {...}

notFound, nonDone, notSuccessful 과 같은 이름은 변수의 값이 부정이 됐을 때 읽기 어렵다.

  • 접두어 is

자바에서는 접두어 is 를 붙여 불린 메소드나 변수명을 짓는다. 그러나, 접두어가 없는 이름이 읽고 이해하는데 더 쉬운 경우가 있다.

if(isfound) {...}
if(found) {...}

접두어 isfound 보다 is 를 붙이지 않은 found 가 오히려 더 쉽게 읽힌다.

메소드가 여러번 호출된 한눈에 보기 힘든 코드

private static final String FORMAT_SYMBOL = "//(.*)\\\\n(.*)";

public static List<String> customSplit(String input) {
    Matcher matcher = Pattern.compile(FORMAT_SYMBOL).matcher(input);
    if (matcher.find()) {
        return Arrays.asList(matcher.group(2).split(Pattern.quote(matcher.group(1))));
    }
    ...
}

위 코드의 리턴 부분을 보았을 때, 한 줄에 많은 기능이 있어서 코드 읽기가 어렵다.

private static final String FORMAT_SYMBOL = "//(.*)\\\\n(.*)";

public static List<String> customSplit(String input) {
    Matcher matcher = Pattern.compile(FORMAT_SYMBOL).matcher(input);
    if (matcher.find()) {
        String splitSymbol = matcher.group(1);
        String content = matcher.group(2);
        return Arrays.asList(content.split(Pattern.quote(splitSymbol)));
    }
    ...
}

splitSymbol, content 변수로 선언해 줌으로써 이전보다 훨씬 읽기가 수월해진다.

변수 이름에 자료형이 들어간다면?

private List<Double> numberList = new ArrayList<>();
private List<String> operatorList = new ArrayList<>();

List 대신 다른 자료형(Set…)을 써야 하는 경우가 오면 어떻게 해야 할까? 기존 변수명이 적절한 의미를 나타내지 못하게 되므로 결국 변수명을 변경해야 하는 번거로움이 생긴다. 변수 이름에 자료형을 쓰지 않아도 타입을 통해 충분히 어떤 변수인지 파악이 가능하다.

private List<Double> numbers = new ArrayList<>();
private List<String> operators = new ArrayList<>();

List, Collection 등의 자료형은 복수형으로 표현하는 것이 좋다.


참고 링크

  • 효과적인 이름짓기
  • 의미 있는 이름 - 프로그래밍 네이밍방법
  • Clean Code 2장 - 의미 있는 이름