좋은 이름에 대한 고려사항

변수의 이름에 따라 변수의 좋고 나쁨이 크게 좌우된다.

나쁜 변수명의 예제

> x = x - xx;

   xxx = fido + SalesTax(fido);

   x = x + LateFee(x1, x) + xxx;

   x = x + Interest(x1, x);

  //이 코드는 미결재 잔액과 새로 구입한 물건들을 토대로 고객이 지불해야 하는 총 금액을 계산하는 코드..라지만 각 변수의 의미를 알기 힘들다

좋게 수정하면

balance = balance - lastsPayment;

mothlyTotal = newPurchases + SalesTax(newPurchases);

balance = balance + LateFee (customerID, balance) + monthlyTotal;

balance = balance + Interest(customerID, balance);

 

명명(naming)시 가장 중요한 고려사항

변수이름이  변수가 표현하고 있는 것을 완벽하고 정확하게 설명해야 한다는 점이다. 종종 서술문 자체가 가장 좋은 변수 이름인 경우가 있다. 미국 올림픽대표팀에 있는 선수의 수를 표현하는 변수이름은 numberofPeopleOntheUsOlympicTeam일 것이다. 운동장 좌석수를 표현하는 이름은 numberofSeatsInTheStadium일 것이다. 현재의 이자율을 포함하는 변수는 r이나 x보다 rate나 interestRate가 더 좋은 이름이다.

이러한 이름에는 두가지 특징이 있음을 주목하자. 첫째, 판독하기 쉽다. 둘째는 몇몇 이름은 너무 길어서 실용적이지 않다.

이름은 가능한한 구체적이어야 한다. x, temp, i와 같이 한가지 이상의 목적으로 사용되기 쉬운 막연한 이름들은 많은 정보를 제공하지 않기때문에 나쁜이름이 된다.

 

최적의 이름 길이는 10~16자 사이가 적당하다고들 한다.

 

범위가 변수 명에 미치는 효과

전역공간(namespace)에 있는 이름들에는 한정자(qualifier)를 사용하라

 

변수이름에서의 계산값 한정자 - 많은 프로그램들은 계산된 값(총계, 평균, 최대값 등)을 보관하는 변수들을 갖는다. 만약 Total, Sum, Average, Max, Min, Record, String, Pointer와 같은 한정자로 변수의 이름을 수정한다면, 이름의 끝에 수정자를 입력한다. 이런 습관의 장점은 첫째, 변수 이름에서 가장 중요한 부분, 즉 변수의 의미를 가장 잘 전달하는 부분은 앞부분이기때문에 가장 눈에 띄고 가장 먼저 읽혀야 한다.  둘째, 이러한 규약을 마련함으로써 totalRevenue와 revenueTotal을 같은 프로그램에서 사용하게 되는 혼란을 피하게 된다. 셋째, revenueTotal, expenseTotal, revenueAverage와 같은 이름들은 정렬된 느낌을 주지 않는다. 마지막으로 일관성은 가독성을 향상시키고 유지보수를 쉽게 한다.

 

변수이름의 일반적인 반의어

  • begin/end
  • first / last
  • locked / unlocked
  • min / max
  • next / previous
  • old / new
  • opened / closed
  • visible / invisible
  • source / target
  • source / destination
  • up / down

 

데이터의 특정 타입에 대한 명명

루프인텍스의 명명

우리는 루프에서 i,j,k같은 이름을 관습적으로 쓴다.

ex 간단한 루프 변수 이름에 대한 자바 예제

for( i = firstItem; i < lastItem; i++)

data[ i ] = 0;

만약 변수가 루프 외부에서 사용되어야 한다면, 반드시 i나 j,k보다는 좀 더 의미 있는 이름을 제공해야 한다. 예를 들어, 파일로부터 레코드를 읽어들이고 얼마나 많은 레코드를 읽었는지 기억해야 한다면, recordCount와 같은 이름이 적절할 것이다.

ex 실명적인 루프변수 이름에 대한 자바 예제

recordCOunt = 0;

while( moreScores())

{

Score[ recordCount ] = GetNextScore();

recordCount ++;

}

//recordCount를 사용하는 코드

만약 루프가 길어진다면, i가 무엇을 나타내는지 잊기 쉽기때문에, 루프의 인덱스에 좀 더 의미 있는 이름을 제공하는 것이 좋을 것이다. 코드는 자주 변경되고 확장되고 다른 프로그램에 복사되기 때문에, 많은 숙련된 프로그래머는 i와 같은 이름들을 피한다. 루프가 길어지는 한가지 이유는 루프가 중첩되기 때문이다. 만약 여러개의 중첩된 루프가 있다면 가독성을 향상시키기 위해서 좀 더 긴 이름으로 루프 변수들을 작성한다

ex 중첩된 루프에서 좋은 루프 이름을 갖는 자바 예제

for ( teamIndex = 0; teamIndex < teamCount; teamIndex++)

{

for( eventIndex = 0; eventIndex < eventCount[ teamIndex ] ; eventIndex++)

{

score[teamIndex][eventIndex] = 0;

}

}

j,i보다는 teamIndex, eventIndex가 많은 정보를 제공한다

 

상태변수의 명명

상태변수에 대해서 flag보다 더 나은 이름을 생각한다.

ex 나쁜 이름을 갖는 플래그에 대한 예제

if ( flag ) ...

if( statusFlag & 0x0F) ...

if( printFlag == 16) ...

if(computeFlag == 0) ...

flag = 0x1;

statusFlag = 0x80;

printFlag = 16;

computeFlag = 0;

 

statusFlag = 0x80와 같은 명령문은 여러분이 코드를 작성하거나 관련문서를 보기전까지는 무엇을 의미하는지 알수 없다

ex상태변수를 잘 사용한 예제

if(dataReady) ...

if(characterType & PRINTABLE_CHAR) ...

if(reportType == ReportType_Annual) ...

if(recalcNeeded == True) ...

dataReady = true;

characterType = CONTROL_CHARACTER;

reportType = ReportType_Annual;

recalcNeeded = false;

이것이 좋은 명명 법이다.

 

임시 변수의 명명

임시변수는 계산의 중간 결과를 보관하기 위한 임시 저장소로 사용되고 보고 수잔으로 사용되는 값을 보관하기 위해 사용된다. 일반적으로 temp, x 또는 그 밖의 모호하고 설명적이지 않은 이름으로 명명된다.

임시변수를 조심해라. 변수의 값을 일시적으로 유지해야 할 필요가 종종있다.

 

ex 정보가 없는 임시 변수의 이름에 대한 예제

// 2차 방정식근을 구하는 코드이고 값은 양수를 가정한다

temp = sqrt(b^2 - 4 * a * c);

root[0] = (-b + temp) / ( 2 * a);

root[1] = ( -b - temp) / (2 * a);

temp가 어떤 값을 가지고 있는지 아무 정보가 없다.

 ex 임시 변수의 이름을 실질적인 변수로 대체한 예제

dicriminant = sqrt(b^2 - 4 * a * c);

root[0] = (-b + dicriminant ) / ( 2 * a);

root[1] = (-b - dicriminant ) / ( 2 * a);

 

boolean 변수의 명명

  • 전형적인 불린 변수의 이름을 기억한다. 다음은 유용하게 사용되는 불린 변수의 이름들이다

    • done - 무언가의 수행이 완료됨을 의미
    • error - 오류가 발생했음
    • found - 값이 발견되었음. 값이 발견되었으면 참 아니면 거짓.
    • soccess | ok - 연산의 성공을 의미.실패하면 거짓
  • 참이나 거짓의 의미를 함축하는 불린 변수의 이름을 사용한다. - 위와 같이 참 거짓이 명확한 명명은 좋지만 status / sourceFile같은 변수명은 참 거짓이 불분명하기때문에 좋지 않다. 어떤 프로그래머는 불린변수이름 앞에 Is를 붙이기 좋아한다. isdone? isError? isFound? 이 질문에 대한 참, 거짓의 대답을 제공한다. 하지만 isStatus?는 말이 안되는 이름인 것이다. 이 접근의 단점은 간단한 논리적인 표현식의 가독성이 떨어진다는 것이다. if(isFound)는 if(found)보다 가독성이 떨어진다.
  • 긍정적인 불린 변수이름을 사용한다 - notFound, notdone, notSuccessful보다는 found/done/processingComplet가 훨씬 좋다.

 

열거 형의 명명

열거형을 사용할때, Color_, Planet_, Month_와 같은 접두사를 사용하여 해당타입의 멤버들이 모두 동일한 그룹에 속한다는 것이 분명하다는 것을 보장할수 있다.

 

상수의 명명

상수를 명명할때 상수가 가르키는 숫자보다는 상수가 표현하는 추상적인 대상으로 명명하도록 한다. FIVE는 나쁜 이름이다. CYCLES_NEEDED는 좋은 이름이다.FIVER = 6.0도 웃긴 이름이다. 마찬가지로 BAKERS_DOZEN은 잘못된 상수이름이며,DONUTS_MAX는 좋은 이름이다.

 

명명 규약의 효과

규약의 장점

  • 더 많은 것을 당연하게 받아들일수 있다
  • 다른 프로젝트에서 활용할수 있다. 유사한 이름은 무엇을 해야 하는지 익숙하지 않은 프로젝트에서 도움을 준다
  • 새로운 프로젝트에서 좀 더 빠르게 코드를 배우는데 도움을 준다. 프로그래머마다 다르게 보일수 있는 코드를 일관성있게 만들어 준다
  • 이름이 늘어나는 것을 줄여준다. 예를 들어 총점을 pointTotal이나 totalPoints로 부를수 있다. 이것은 코드 작성시에는 괜찮지만 가독시 혼란스러울수 있다
  • 언어의 약점을 보완할수 있다
  • 관련된 항목들간의 관계를 강조한다. 객체데이터를 지원하는 언어를 사용한다면 컴파일러가 자동으로 처리하지만 그렇지 않을 경우 명명 규약으로 보완할수 있다. address, phone, name과 같은 이름들의 변수가 있고 직원(employee)와 관련된 변수들이라면 employeeAddress, employeePhone, employeeName 이라 지어보자. 관련성이 눈이 보일 것이다.

 

언제 명명 규약이 필요한가? - 솔직히 항상 필요한 거 같기는 하다.

  1. 한 프로젝트에서 여러 명의 프로그래머가 작업할때
  2. 수정이나 유지보수때문에 프로그램을 다른 프로그래머에게 넘겨주어야 할때(거의 항상)
  3. 조직 내에 있는 다른 프로그래머가 여러분이 작성한 프로그램을 검토할때
  4. 프로그램이 너무 커서 한번에 기억할수 없기때문에 반드시 부분적으로 제쳐두어야 할때
  5. 프로젝트에서 자주 쓰이는 특이한 용어들이 많아서 코드 작성시 사용할 표준 용어나 약어가 필요할때

 

비형식적인 명명 규약

언어에 독립적인 규약을 위한 지침

  • 변수 이름과 루틴 이름을 구별한다 - 변수이름은 소문자로 시작하고 루틴이름은 대문자로 시작하는 경우가 많다
  • 클래스와 객체를 구별한다

    1. 첫번째 문자를 대문자로 작성하여 타입과 변수를 구분함

      ex. LongerWidget longerWidget;

    2. 모든 문자를 대문자로 작성하여 타입과 변수를 구분함

      ex. WIDGET widget; LONGERWIDGET longerWidget;

    3. 타입에 대해서 "t_" 접두사를 작성하여 타입과 변수를 구분함

      ex. t_Widget Widget; t_LongerWidget LongerWidget;

    4. 변수에 대해서 "a"접두사를 작성하여 타입과 변수를 구분함

      ex. Wdiget aWidget; LongerWdiget aLongerWidget;

    5. 보다 구체적인 변수의 이름을 사용하여 타입과 변수를 구분함

      ex. Widget employeeWidget; LongerWidget fullEmployeeWidget;

      1~5는 각각 tradeoff가 있다. 각자 사용하는 언어의 특성에 맞추어 알아서 사용하면 된다. 예를 들어 1번째 경우 VB에서는 widget과 Widget을 같은 토큰으로 간주해서 사용할수 없다.

전역 변수를 식별한다 - 예를 들어 "g_"같은 접두어를 붙여서 식별한다

멤버변수를 식별한다 - 예를 들어 "m_"같은 접두어

형 선언을 식별한다 - 접두어 "t_"

명명된 상수를 식별한다

열거형의 요소를 식별한다

입력만 하는 매개변수를 지정할수 없는 언어에서는 이를 식별한다

가독성을 강화시키기 위해서 이름을 형식화한다- 가독성을 높이기 위해서 대문자를 사용하는 방법과 공백문자를 사용하는 방법이 있다. GYMNASTICSPOINTTOTAL은 gymnasticsPoi0ntTotal이나 gymastics_point_total보다 가독성이 떨어진다. 이런 기법은 섞어서 사용하지는 말자.

 

특정언어에 대한 지침. - 너무 구체적임으로 책 참고 - p395~p397.게다가 현재 난 AS를 사용한다

 

표준화된 접두사들

표준화된 접두사는 사용자 정의 타입의 축약형(User-Defined Type, UDT)와 의미적인 접두사로 나눈다.

UDT - 특정 프로그램을 위해서 작성한 짧은 코드로 기술한 후, 그 프로그램에서 사용하기 위하여 표준화한다

아래 표는 워드 프로세서를 위한 프로그램에 사용할수 있는 간단한 UDT목록이다.

UDT 축약형 의미
ch 문자에서(c++에서의 문자가 아니라 워드 프로세서 프로그램 문서에 있는 문자를 표현하기 위한 데이터형
doc 문서.document
pa paragraph
scr 화면 영역(screen region)
sel 선택(selection)
wn 윈도우(window)

의미적 접두사 - 의미적 접두사는 UDT보다 한 단계 더 나아가서 변수나 객체가 어떻게 사용되는지를 설명한다

의미적 접두사 의미
c 카운트(count), 레코드나 문자 등의 수에서 사용된다
first 배열에서 다루어져야 하는 첫번째(first)요소이다. first는 min과 유사하지만 배열 자체보다는 현재의 연산과 관계가 있다
g 전역변수
i 배열에 대한 인덱스
last 배열에서 다루어져야 하는 마지막(last)요소이다. last는 first의 반대
lim 배열에서 다루어져야 하는 요소의 상한ㄱ밧
m 클래스 수준의 변수
max 배열이나 다른 종류의 리스트에서 절대적인 마지막 요소. max는 배열에 대한 연산보다는 배열자체를 가르킨다
min 배열이나 다른 종류의 리스트에서 절대적인 첫번째 요소
p 포인터

표준화된 접두사의 장점

모호해지기 쉬운 명명 영역을 정교하게 만든다. min과 first, last, max간의 정확한 구분은 특히 도움이 된다.

간결한 이름을 만든다. 예를 들어 단락수를 나타내기 위해 totalParagraphs 대신 단락수로 cpa를 사용할수 있고 indexParagraphs나 paragraphsIndex대신에 단락배열에 대한 인덱스를 구별하기 위해서 ipa를 사용할수 있다.

표준화된 접두사를 이용하면 컴파일러가 검사할수 없는 추상 데이터 형을 사용하고 있을 때 타입을 정확하게 검사할수 있다. paReformat = docReformat은 pa와 doc가 서로 다른 UDT이기때문에 아마 틀렸을 것이다.

표준화된 접두사의 가장 큰 위험은 프로그래머가 접두사에 이어서 변수에 의미 있는 이름을 제공하려고 하지 않는 다는 점이다.

 

읽기 쉬운 짧은 이름

일반적인 축약 지침

  • 표준 축약어를 사용한다(사전에 나와 있는 널리 사용되는 용어)
  • 불필요한 모음을 제거한다(ex. computer > cmptr, screen > scrn, apple > appl, integer > intgr) -> 한국인이라 그런지 공감 안됨. 더 모르겠음
  • 관사(and, or, the )를 제거한다
  • 각 단어의 첫번째 문자나 처음의 몇 문자를 사용한다
  • ...

축약어에 대한 의견.

-->별공감은 가지 않지만 한가지는 기억해둘만 하다. 주요 축약어에 대한 설명을 주석으로 넣어둔다.

ex. xPos x값의 위치 . 이런 식으로.

 

피해야 할 종류의 이름

  • 오해의 소지가 있는 이름이나 축약어를 피한다
  • 유사한 의미를 갖는 이름을 피한다
  • 의미는 다르지만 유사한 이름의 변수를 피한다
  • "개"와 "게"처럼 비슷하게 들리는 이름을 피한다 > 동의이의어
  • 이름에서 숫자를 피한다 - 예를 들어 file1과 file2 또는 total1과 total2는 피한다.
  • 이름에 철자가 틀린 경우가 없도록 한다
  • 일반적으로 틀리기 쉬운 단어는 피하도록 한다- 철자가 미국인도 헷갈리는 것들이 참 많구나
  • 대문자 만드로 변수의 이름을 차별화하지 않는다.
  • 여러개 언어의 사용을 피한다
  • 표준형, 변수, 루틴의 이름을 피한다 - 일밙적으로 예약어.
  • 변수가 표현하는 것과 전혀 관련이 없는 이름을 사용하지 않는다
  • 읽기 어려운 문자를 포함하는 이름을 피한다

 

 

요점정리

  • 좋은 변수 이름은 프로그램의 가독성에 있어서 핵심적인 요소이다
  • 이름은 가능한한 구체적이어야 한다
  • 명명규약은 지역, 클래스, 전역 데이터를 구분한다. 그리고 형이름, 명명된 상수, 열거형, 변수를 구분한다
  • 축약어는 현대적인 프로그래밍 언어에서는 거의 필요하지 않다.
  • 코드는 작성되는 것보다 훨씬 많이 읽혀진다. 여러분이 선택한 이름이 작성 시간 편의성보다 읽기 시간 편의성에 유리하도록 한다

이 글은 스프링노트에서 작성되었습니다.

by 무위자연 2008. 1. 19. 16:58