Copyright (c) 1999 Scott Ambler, Ambysoft, Inc.

Java 코딩 가이드라인은 Scott Ambler, Ambysoft Inc.(www.ambysoft.com)의 라이센스에 따라 제공되며 Rational Unified Process에 포함하기 위해 형식이 재구성되었습니다.


목차

1      소개
       
1.1    기본 가이드라인

2    코딩 표준
     
2.1    이름 지정 규칙
      2.2    문서화 규칙
              2.2.1  Java 주석 유형
              2.2.2  javadoc에 대한 빠른 개요   

3    구성원 함수 표준
     
3.1    구성원 함수 이름 지정
              3.1.1    액세서 구성원 함수 이름 지정
                         3.1.1.1    Getter
                         3.1.1.2    Setter
      3.2    생성자 이름 지정
      3.3    구성원 함수 가시성
      3.4    구성원 함수 문서화
               3.4.1    구성원 함수 헤더
               3.4.2    내부 문서화
      3.5    정확한 코드 작성 기법
               3.5.1    코드 문서화
               3.5.2    코드의 단락 나누기 또는 들여쓰기
               3.5.3    코드에 공백 사용
               3.5.4    30초 규칙 준수
               3.5.5    짧은 한 줄 명령행 작성
               3.5.6    연산 순서 지정

4    필드 및 특성 표준
      4.1    필드 이름 지정
              4.1.1    컴포넌트 (위지트(widget)) 이름 지정
                         4.1.1.1    컴포넌트 이름 지정 대안: 헝가리안 표기법
                         4.1.1.2    컴포넌트 이름 지정 대안: 접미사-헝가리안 표기법
                         4.1.1.3    컴포넌트 이름 표준 설정
              4.1.2    상수 이름 지정
               4.1.3    콜렉션 이름 지정
      4.2    필드 가시성
               4.2.1    이름을 "숨기지" 않음
      4.3    필드 문서화
      4.4    액세서 구성원 함수 사용
              4.4.1    액세서를 사용하는 이유               
                          4.4.1.1   액세서를 사용하지 않는 경우
              4.4.2    액세서 이름 지정
              4.4.3    고급 액세서 기법
                         4.4.3.1    초기화 지연
                         4.4.3.2    
상수 액세서
                         4.4.3.3    
콜렉션 액세서
                         4.4.3.4    여러 필드에 동시 액세스   
      4.5    액세서 가시성
      4.6    항상 정적 필드 초기화

5    로컬 변수 표준
      5.1    로컬 변수 이름 지정
                  5.1.1    스트림 이름 지정
                   5.1.2    루프 카운터 이름 지정
                   5.1.3    예외 오브젝트 이름 지정
        5.2   로컬 변수 선언 및 문서화
               5.2.1     선언에 대한 일반 주석

6    구성원 함수에 대한 매개변수 표준
     
6.1    매개변수 이름 지정
      6.2    매개변수 문서화
               6.2.1    매개변수 유형에 따른 인터페이스 사용

7    클래스, 인터페이스, 패키지 및 컴파일 단위 표준
      7.1    클래스 표준
                7.1.1    클래스 이름 지정
                7.1.2    클래스 문서화
                7.1.3    클래스 선언
                7.1.4    public 및 protected 인터페이스 최소화
                            7.1.4.1    public 인터페이스 우선 정의
      7.2     인터페이스 표준
                7.2.1    인터페이스 이름 지정
                            7.2.1.1    대체
                7.2.2    인터페이스 문서화
      7.3     패키지 표준
                7.3.1    패키지 이름 지정
                7.3.2    패키지 문서화
      7.4     컴파일 단위 표준
                7.4.1    컴파일 단위 이름 지정
                7.4.2    컴파일 단위 문서화

8    오류 처리 및 예외

9    기타 표준 및 문제
      9.1    재사용
      9.2    클래스 가져오기
      9.3    Java 코드 최적화
      9.4    Java 테스트 하니스 작성

10    성공 패턴
       10.1    효과적인 표준 사용
       10.2    성공적인 코드 작성을 위한 기타 요인

11    요약
       
11.1    Java 이름 지정 규칙
        11.2    Java 문서화 규칙
                   11.2.1    Java 주석 유형
                   11.2.2    문서화 내용
        11.3    Java 코딩 규칙(일반)

12    참조

13    용어집


1    소개

이 문서에서는 견고한 Java 코드를 작성하기 위한 표준, 규약 및 가이드라인의 콜렉션에 대해 설명합니다. 이는 쉽게 이해할 수 있으며 유지보수 및 강화 작업이 용이한 코드를 생성할 수 있는 견고하고 입증된 소프트웨어 엔지니어링 원칙을 기반으로 합니다. 또한 이러한 코드 표준을 따름으로써 Java 개발자의 생산성이 현저히 향상됩니다. 처음부터 우수한 코드를 작성하는 데 시간을 할애하면 개발 프로세스에서 보다 쉽게 수정할 수 있음을 경험을 통해 알 수 있습니다. 마지막으로 공통 코딩 표준 세트를 따름으로써 일관성이 향상되고 개발자 팀의 생산성 또한 현저히 향상됩니다.

1.1    기본 가이드라인 

상식을 따르십시오. 규칙 또는 가이드라인이 없거나 규칙이 명확히 적용되지 않거나 어떤 방법으로도 실패하는 경우 상식선에서 기본 원칙을 확인하십시오. 이 규칙은 다른 모든 규칙에 우선합니다. 즉, 가장 필요한 요소는 상식입니다.


2    코딩 표준

Java 코딩 표준은 자신과 팀 구성원의 코드에서 일관성을 향상시킨다는 점에서 중요합니다. 일관성 있는 코드는 이해하기에도 쉽고 개발 및 유지보수 또한 용이하며 이를 통해 작성하는 응용프로그램의 전체 비용을 절감시킵니다.

Java 코드는 개발자가 다른 프로젝트를 수행하기 위해 이동한 후에도 장기간 계속 남아 있습니다. 따라서 개발 중 중요한 목적은 자신의 작업을 다른 개발자 또는 다른 개발자 팀에게 인계한 후에도 새로운 작업자가 기존 코드 이해를 위한 불필요한 노력 없이 기존 작업을 계속 유지보수 및 강화할 수 있도록 하는 것입니다. 이해하기 어려운 코드는 폐기 후 재작성될 위험성이 있습니다.

2.1    이름 지정 규칙

이 문서에서는 표준을 사용한 이름 지정 규칙에 대해 설명하며 이와 관련된 몇 가지 기본 사항은 다음과 같습니다.

  1. 변수, 필드 및 클래스를 정확히 설명하는 완전한 영어 설명자를 사용하십시오. 예를 들어, firstName, grandTotal 또는 CorporateCustomer와 같은 이름을 사용하십시오. x1, y1 또는 fn과 같이 짧은 이름은 입력하기는 쉽지만 나타내려는 내용을 알 수 없어 코드를 이해, 유지보수 및 강화하기 어렵습니다.
  2. 해당 분야에서 사용되는 용어를 사용하십시오. 사용자가 클라이언트(Client)를 고객(Customer)으로 나타내는 경우 클래스에 Client가 아닌 Customer를 사용하십시오. 많은 개발자는 해당 산업 또는 분야에 정확한 용어가 있는데도 일반 개념의 용어를 작성하는 실수를 저지릅니다.
  3. 이름에 대소문자를 혼합하여 쉽게 읽을 수 있게 하십시오. 일반적으로는 소문자를 사용하되, 클래스 이름 및 인터페이스 이름의 첫 번째 문자와 중간 단어 및 마지막 단어의 첫 번째 문자에는 대문자를 사용하십시오. [KAN97]
  4. 약어는 되도록 사용하지 않고 반드시 필요한 경우에만 사용하십시오. 즉, 표준 단축 양식(약어)의 목록을 유지보수하고 이 목록에서 현명하게 선택하며 일관성있게 사용해야 합니다. 예를 들어, "number"라는 단어의 단축 양식을 사용하려는 경우 nbr, no 또는 num 중 하나를 선택한 다음 선택한 양식을 문서화하고(무엇을 선택하든 관계 없음) 해당 양식만 사용하십시오.
  5. 긴 이름은 사용하지 마십시오(15자 미만이 좋음). 경우에 따라 클래스 이름 PhysicalOrVirtualProductOrService가 올바른 클래스 이름으로 보이지만 이 이름은 너무 길기 때문에 Offering과 같이 보다 짧은 이름으로 바꿔야 합니다.
  6. 대소문자만 다르거나 유사한 이름을 사용하지 마십시오. 예를 들어, 변수 이름 persistentObjectpersistentObjects는 함께 사용하면 안되고 anSqlDatabaseanSQLDatabase도 함께 사용하면 안됩니다.
  7. 이름 앞뒤에 밑줄을 사용하지 마십시오. 앞뒤에 밑줄이 있는 이름은 일반적으로 시스템 용도로 예약된 이름이므로 사용자가 작성하는 이름에는 사용해서는 안됩니다. 무엇보다도 밑줄은 입력하기가 번거롭고 어려우므로 가능한 경우 사용하지 마십시오.

2.2    문서화 규칙

이 문서에서는 또한 문서화 규칙에 대해 설명하며 이와 관련된 몇 가지 기본 사항은 다음과 같습니다.

  1. 주석은 코드의 명확성을 더하기 위한 것이어야 합니다. 코드를 문서화하는 이유는 본인은 물론 동료 및 다음 사용자가 코드를 쉽게 이해할 수 있도록 하기 위해서입니다.
  2. 프로그램을 문서화할 필요가 없다면 실행할 가치도 없는 프로그램일 것입니다. [NAG95]
  3. 꾸미지 마십시오. 즉, 배너와 같은 주석은 사용하지 마십시오. 1960년대 및 1970년대에는 COBOL 프로그래머가 내부 주석 주위에 일반적으로 별표를 사용하여 상자를 그리곤 했습니다. 이러한 장식은 프로그래머의 예술적 충동에 대한 배출구는 되겠지만 최종 제품의 가치는 거의 제공하지 않는 시간 낭비일 뿐이라고 할 수 있습니다. 즉, 예쁜 코드가 아닌 간결한 코드를 작성해야 합니다. 또한 어차피 코드를 표시하고 인쇄하는 데 사용되는 글꼴 중 일부에서 상자가 올바르게 정렬되지 않습니다.
  4. 주석은 간단하게 작성하십시오. 가장 올바른 주석은 간단하면서도 요점이 있는 설명입니다. 개발자가 해야 할 일은 책을 쓰는 것이 아니라 다른 사람들이 코드를 이해할 수 있도록 충분한 정보를 제공하는 것입니다.
  5. 코드를 작성하기 전에 문서를 작성하십시오. 가장 효과적인 코드 문서화 방법은 코드를 작성하기 전에 주석을 작성하는 것입니다. 주석을 작성함으로써 코드를 작성하기 전에 코드 실행 원리를 생각해 볼 수 있으며 해당 코드를 실제로 작성할 수 있는지 확인할 수 있습니다. 또는 적어도 코드를 작성할 때 동시에 문서화해야 합니다. 문서화를 통해 코드를 보다 쉽게 이해할 수 있으므로 개발 과정에서 이를 활용할 수 있습니다. 주석 작성에 시간을 투자하는 만큼 이점을 얻을 수 있어야 합니다. [AMB98]
  6. 단순한 수행 내용이 아닌 이유를 문서화합니다. 예를 들어, 다음 예제 1의 코드는 $1,000 이상의 주문 시 5% 할인이 제공됨을 나타냅니다. 이 경우 할인이 적용되는 이유는 대량 구매 시 할인 서비스를 제공하는 비즈니스 규칙 때문일 수 있습니다. 또한 대량 구매에 따른 시간별 특별 판매가 있거나 모든 대량 구매에 대해 할인이 적용될 수도 있습니다. 또는 최초 프로그래머의 성품이 너그러웠던 것일 수도 있습니다. 어쨌든 해당 이유를 소스 코드 내부 또는 외부 문서 등 어딘가에 문서화하지 않으면 알 수 없습니다.

예제 1:

if ( grandTotal >= 1000.00)

{

grandTotal = grandTotal * 0.95;

}

2.2.1    Java 주석 유형

Java에는 다음과 같은 세 가지 스타일의 주석이 있습니다. 

다음 차트는 각 주석 유형에 대해 제안되는 사용법의 요약과 몇 가지 예제입니다.

주석 유형 사용법 예제
문서화 문서화 주석은 문서화할 인스턴스, 클래스, 구성원 함수 및 필드에 대한 선언 바로 앞에서 사용됩니다. 문서화 주석은 javadoc(아래 참조)에서 클래스에 대한 외부 문서화를 작성하기 위해 처리됩니다. /**
Customer: A customer is any person or organization that we sell services and products to.
@author S.W. Ambler
*/
C 스타일 C 스타일 주석은 더 이상 적용되지 않지만 사용자의 마음이 바뀌는 경우에 대비하여 유지하려는 코드 행을 문서화하는 데 사용됩니다. 또는 디버깅 작업 시 일시적으로 꺼두기 위해 사용할 수도 있습니다. /*
This code was commented out by B. Gustafsson on June 4, 1999 because it was replaced by the preceding code. Delete it after two years if it is still not applicable.
. . . (소스 코드)
*/
단일 행 단일 행 주석은 구성원 함수 내부에서 비즈니스 로직, 코드 섹션 및 임시 변수 선언을 문서화하는 데 사용됩니다. // Apply a 5% discount to all
// Invoices Over $1000 Due To
// generosity campaign started in
// Feb. of 1995.

중요한 것은 조직에서 C 스타일 주석 및 단일 행 주석 사용 방법에 대한 표준을 설정한 후 해당 표준을 일관되게 준수해야 한다는 것입니다. 비즈니스 로직을 문서화하는 데 한 가지 유형을 사용하고 이전 코드를 문서화하는 데 다른 유형을 사용하십시오. 단일행 주석의 경우 코드와 동일한 행에 문서화 내용을 배치(인라인)할 수 있으므로 비즈니스 로직에 사용하십시오. C 스타일 주석의 경우 한 번에 여러 행을 주석 처리할 수 있으므로 이전 코드를 문서화하는 데 사용하십시오. C 스타일은 문서화 주석과 모양이 매우 유사하므로 혼동을 피하기 위해 다른 곳에서는 사용하지 마십시오.

엔드라인 주석에 대한 논의-[MCO93]에서는 엔드라인 주석 또는 행 끝 주석이라고도 하는 인라인 주석 사용에 대한 강한 반대 의견을 제시합니다. 저자 McConnell은 코드의 시각적 구조를 방해하지 않도록 주석을 코드 오른쪽에 맞춰야 한다고 주장합니다. 이러한 경우 형식화하기가 쉽지 않습니다. 그리고 "주석을 많이 사용하는 경우 맞추는데 시간이 많이 소요됩니다. 그러한 시간은 코드에 대한 정보를 얻는 시간이 아닌 전적으로 스페이스바 또는 Tab 키를 누르는 단순한 작업에 소요되는 시간입니다." 그는 또한 엔드라인 주석의 경우 행의 코드 길이가 늘어나면 유지보수하기가 어렵다고 지적합니다. 이러한 경우 엔드라인 주석과 충돌하게 되며 이를 맞추려면 나머지에 대해서도 동일한 작업을 수행해야 한다고 지적합니다.

2.2.2        javadoc에 대한 빠른 개요

Sun의 JDK(Java Development Kit)에는 Java 코드 파일을 처리하고 Java 프로그램에 대한 HTML 파일 형식의 외부 문서를 생성하는 javadoc라는 프로그램이 포함되어 있습니다. Javadoc는 제한된 수의 태그(문서화 섹션 시작을 표시하는 예약어)를 지원합니다. 자세한 정보는 JDK javadoc 문서를 참조하십시오.

태그 사용 목적 목적
@author name 클래스, 인터페이스 특정 코드의 작성자를 나타냅니다. 작성자당 하나의 태그를 사용해야 합니다.
@deprecated 클래스, 구성원 함수 클래스의 API가 폐기되어 더 이상 사용해서는 안됨을 나타냅니다.
@exception name description 구성원 함수 구성원 함수로 인해 발생하는 예외에 대해 설명합니다. 예외당 하나의 태그를 사용하고 예외에 대한 전체 클래스 이름을 제공해야 합니다.
@param name description 구성원 함수 해당 유형 또는 클래스와 사용법을 포함하여 구성원 함수로 전달된 매개변수에 대해 설명하는 데 사용됩니다. 매개변수당 하나의 태그를 사용하십시오.
@return description 구성원 함수 구성원 함수의 리턴값(있는 경우)에 대해 설명합니다. 유형 또는 클래스와 리턴값의 잠재적 사용법을 나타내야 합니다.
@since 클래스, 구성원 함수 항목의 지속 기간을 나타냅니다(예: since JDK 1.1).
@see ClassName 클래스, 인터페이스, 구성원 함수, 필드 지정된 클래스에 대한 하이퍼텍스트 링크를 문서에서 생성합니다. 완전한 클래스 이름을 사용할 수 있으며 일반적으로 해당 이름을 사용해야 합니다.
@see ClassName#member functionName 클래스, 인터페이스, 구성원 함수, 필드 지정된 구성원 함수에 대한 하이퍼텍스트 링크를 문서에서 생성합니다. 완전한 클래스 이름을 사용할 수 있으며 일반적으로 해당 이름을 사용해야 합니다.
@version text 클래스, 인터페이스 특정 코드에 대한 버전 정보를 나타냅니다.

코드 문서화 방법은 최초 작성자의 생산성 뿐만 아니라 나중에 코드를 유지보수하고 강화하는 사용자의 생산성에도 큰 영향을 줍니다. 개발 프로세스 초기에서 코드를 문서화하는 경우 로직을 검토한 후 코드를 작성하므로 생산성이 보다 향상됩니다. 또한 몇 일 또는 몇 주 전에 작성한 코드를 다시 확인할 때 해당 내용이 이미 문서화되어 있으므로 작성 시 본인의 생각을 쉽게 확인할 수 있습니다.


3    구성원 함수 표준

오늘 작성하는 코드는 앞으로도 수년 동안 계속 사용되며 본인 이외의 다른 사용자가 유지보수하고 강화하게 된다는 사실을 항상 염두에 두어야 합니다. 따라서, 코드를 가능한 "분명"하고 이해하기 쉽게 작성하기 위해 노력해야 하며 이를 통해 유지보수 및 강화 작업을 보다 쉽게 수행할 수 있습니다.

3.1    구성원 함수 이름 지정

구성원 함수의 이름은 전체 영어 설명을 사용하여 지정하되, 첫 단어를 제외한 모든 단어의 첫 번째 문자는 대문자를 사용하여 대소문자를 혼합하여 사용해야 합니다. 또한 구성원 함수 이름의 첫 번째 단어는 강한 능동형의 동사를 사용하는 것이 일반적입니다.

예제:

openAccount()

printMailingLabel()

save()

delete()

이 규칙을 적용하면 이름만으로도 해당 목적을 판별할 수 있는 구성원 함수가 생성됩니다. 이 규칙을 적용하는 경우 일반적으로 이름이 더 길어져서 개발자가 약간의 입력 작업을 더 수행해야 하지만 코드를 보다 쉽게 이해할 수 있으므로 충분한 가치가 있습니다.

3.1.1    액세서 구성원 함수 이름 지정

다음 장에서는 필드(필드 또는 특성) 값을 가져오고 설정하는 구성원 함수인 액세서에 대해 자세히 설명합니다. 그러나 액세서 이름 지정 규칙에 대해서는 다음과 같이 요약 설명합니다.

3.1.1.1    Getter 

Getter는 필드 값을 리턴하는 구성원 함수입니다. 이 경우 필드 이름의 접두부로 "get"을 추가해야 합니다. 필드가 부울 필드가 아닌 경우 필드 이름의 접두부로 "get" 대신 "is"를 추가해야 합니다.

예제:

getFirstName()

getAccountNumber()

isPersistent()

isAtEnd()

이 이름 지정 규칙을 따르면 구성원 함수가 오브젝트 필드를 리턴하며, 부울 Getter의 경우 true 또는 false를 리턴합니다. 이 표준을 사용하는 데 따른 또 다른 이점은 Getter 구성원 함수에 대해 BDK(Beans Development Kit)에서 사용하는 이름 지정 규칙을 따른다는 것입니다. [DES97] "get"의 가장 큰 단점은 불필요한 입력 작업이 추가된다는 점입니다.

Getter에 대한 대체 이름 지정 규칙으로는 has와 can이 있습니다.

올바른 영어 규칙을 기반으로 할 때 가장 적합한 대안은 부울 Getter의 접두부로 "is" 대신 "has" 또는 "can"을 사용하는 것입니다. 예를 들어, hasDependents()canPrint()와 같은 Getter 이름은 코드를 읽을 때 해당 의미를 쉽게 이해할 수 있도록 합니다. 이 접근 방식의 문제점은 아직 이 이름 지정 전략에서는 BDK가 선택되지 않는다는 것입니다. 이러한 구성원 함수의 이름은 isBurdenedWithDependents()isPrintable()로 바꿀 수 있습니다.

3.1.1.2    Setter

Setter(Mutator라고도 함)는 필드 값을 수정하는 구성원 함수입니다. 이 경우 필드 유형에 관계 없이 필드 이름의 접두부로 "set"을 추가해야 합니다.

예제:

setFirstName(String aName)

setAccountNumber(int anAccountNumber)

setReasonableGoals(Vector newGoals)

setPersistent(boolean isPersistent)

setAtEnd(boolean isAtEnd)

이 이름 지정 규칙을 따르면 구성원 함수가 오브젝트 필드 값을 설정한다는 사실을 분명하게 할 수 있습니다. 이 표준을 사용하는 데 따른 또 다른 이점은 Setter 구성원 함수에 대해 BDK에서 사용하는 이름 지정 규칙을 따른다는 것입니다. [DES97] "set"의 가장 큰 단점은 불필요한 입력 작업이 추가된다는 점입니다.

3.2    생성자 이름 지정

생성자는 오브젝트를 처음 작성할 때 필요한 모든 초기화를 수행하는 구성원 함수입니다. 생성자에는 항상 해당 클래스와 동일한 이름이 부여됩니다. 예를 들어, Customer 클래스의 생성자는 Customer()가 됩니다. 이때, 동일한 대소문자를 사용해야 합니다.

예제:

Customer()

SavingsAccount()

PersistenceBroker()

이 이름 지정 규칙은 Sun Microsystems가 설정하는 것이므로 반드시 준수해야 합니다.

3.3    구성원 함수 가시성

클래스 간 결합을 최소화하는 올바른 디자인을 위한 일반 규칙은 구성원 함수의 가시성을 설정할 때 최대한 제한적으로 설정하는 것입니다. 구성원 함수가 public 함수가 아니어도 되는 경우 protected로 작성하고, protected 함수가 아니어도 되는 경우 private으로 작성합니다.

가시성 설명 올바른 사용법
public public 구성원 함수는 다른 오브젝트 또는 클래스의 다른 구성원 함수로 호출할 수 있습니다. 구성원 함수가 정의된 클래스 계층 구조 외부의 클래스 및 오브젝트가 구성원 함수에 액세스할 수 있어야 하는 경우
protected protected 구성원 함수는 함수가 정의된 클래스, 해당 클래스의 서브클래스 또는 동일한 패키지의 클래스에 속하는 구성원 함수로 호출할 수 있습니다. 구성원 함수가 클래스 계층 구조 또는 패키지에서 내부적으로(외부적이 아님) 필요한 동작을 제공하는 경우
private private 구성원 함수는 서브클래스가 아닌 함수가 정의된 클래스의 다른 구성원 함수로만 호출할 수 있습니다. 구성원 함수가 클래스 특정 동작을 제공하는 경우. private 구성원 함수는 일반적으로 리팩토링(재구성이라고도 함)의 결과입니다. 리팩토링이란 하나의 특정 동작을 캡슐화하기 위한 클래스 내 다른 구성원 함수의 동작입니다.
default 기본적으로, 가시성은 지정되지 않으며 함수가 정의된 클래스 또는 동일한 패키지의 클래스에 속하는 다른 구성원 함수로만 함수를 호출할 수 있습니다. 구성원 함수가 외부적으로 또는 서브클래스에 의해서가 아닌 동일한 패키지 내 클래스에서 필요한 동작을 제공하는 경우

3.4    구성원 함수 문서화

구성원 함수를 문서화하는 방법은 일반적으로 이해 가능 여부와 그에 따른 유지보수 및 확장 가능성에 대한 요인을 결정하는 것입니다.

3.4.1    구성원 함수 헤더

모든 Java 구성원 함수에는 소스 코드 맨 위에 함수를 이해하는 데 중요한 모든 정보를 문서화하는 일종의 헤더가 포함되어야 하며 이러한 헤더를 구성원 함수 문서화라고 합니다. 이 정보에는 다음과 같은 내용이 포함되며 이 내용으로만 한정되지는 않습니다.

  1. 함수의 기능 및 해당 이유. 구성원 함수가 수행하는 기능을 문서화함으로써 다른 사용자가 코드의 재사용 가능 여부를 쉽게 판별할 수 있습니다. 또한 함수가 수행하는 기능의 이유를 문서화함으로써 다른 사용자가 해당 코드를 컨텍스트에 쉽게 배치할 수 있습니다. 나아가 다른 사용자가 실제로 코드를 새로 변경해야 하는지 여부를 쉽게 판별할 수 있습니다. 일반적으로 새로운 변경 이유가 처음 코드가 작성된 이유와 충돌할 수 있습니다.
  2. 매개변수로서 전달해야 하는 구성원 함수. 또한 구성원 함수로 전달되어야 하는 매개변수와 사용 방법을 표시해야 합니다. 이 정보를 통해 다른 프로그래머가 구성원 함수로 전달될 정보를 확인할 수 있습니다. 이를 위해서는 2.2.2, javadoc에 대한 빠른 개요 섹션에서 설명하는 javadoc @param 태그가 사용됩니다.
  3. 구성원 함수가 리턴하는 내용. 다른 프로그래머가 리턴값 또는 오브젝트를 올바르게 사용할 수 있도록 구성원 함수가 리턴하는 내용(있는 경우)을 문서화해야 합니다. 이를 위해서는 2.2.2, javadoc에 대한 빠른 개요 섹션에서 설명하는 javadoc @return 태그가 사용됩니다.
  4. 알려진 버그. 구성원 함수와 관련하여 해결되지 않은 문제점을 문서화하여 다른 개발자가 구성원 함수의 단점과 문제를 이해할 수 있도록 해야 합니다. 특정 버그가 클래스 내 여러 구성원 함수에 적용되는 경우, 대신 클래스에 대해 문서화해야 합니다.
  5. 구성원 함수로 인해 발생하는 예외. 다른 프로그래머가 새 코드에서 유의해야 할 사항을 알 수 있도록 구성원 함수로 인해 발생하는 모든 예외를 문서화해야 합니다. 이를 위해서는 2.2.2, javadoc에 대한 빠른 개요 섹션에서 설명하는 javadoc @exception 태그가 사용됩니다.
  6. 가시성 결정. 다른 개발자가 구성원 함수의 가시성 선택과 관련하여 의문을 제기하는 경우 해당 결정사항을 문서화해야 합니다(일반적으로 다른 오브젝트가 아직 구성원 함수를 호출하지 않는데 구성원 함수를 public으로 작성한 경우). 이러한 문서화를 통해 다른 개발자에게 자신의 생각을 명확히 알림으로써 작업 관련 문제에 대한 불필요한 걱정을 하지 않아도 됩니다.
  7. 구성원 함수가 오브젝트를 변경하는 방법. 구성원 함수가 오브젝트를 변경하는 경우(예: 은행 계정의 withdraw() 구성원 함수가 계정 잔액을 수정하는 경우), 해당 내용을 표시해야 합니다. 이 정보를 통해 다른 Java 프로그래머가 구성원 함수 호출에 따른 대상 오브젝트에 대한 영향을 정확히 파악할 수 있습니다.
  8. 작성자, 전화번호, 작성 및 수정 날짜 및 유닛 위치(또는 파일 이름)와 같은 정보를 포함하는 헤더를 사용하지 않습니다. 이러한 정보는 금방 쓸모없는 이전 정보가 되기 때문입니다. 소유권 및 저작권 정보는 유닛 끝에 배치합니다. 예를 들어, 사용자는 프로그램 이해에 유용하지 않은 2 - 3페이지 분량의 텍스트 또는 저작권 사항과 같이 프로그램 정보를 전혀 제공하지 않는 텍스트를 건너뛰려고 합니다. 시각적으로 지저분하고 일관되게 유지하기 어려운 세로줄, 닫힌 프레임 또는 상자를 사용하지 마십시오. 형상 관리 도구를 사용하여 유닛 히스토리를 보존합니다.
  9. 필요한 경우 구성원 함수를 호출하는 방법 예제. 코드 작동 원리를 가장 쉽게 판별할 수 있는 방법 중 하나는 예제를 보는 것입니다. 따라서 구성원 함수 호출 방법에 대한 한두 가지 예제를 포함할 수 있습니다.
  10. 해당 전제 조건 및 사후 조건. 전제 조건은 구성원 함수가 올바른 기능을 수행할 수 있는 제한 조건이고 사후 조건은 구성원 함수 실행이 완료된 후 충족되는 특성 또는 검증입니다. [MEY88] 대부분의 경우, 전제 조건과 사후 조건은 구성원 함수를 작성할 때 적용한 가정에 대해 설명합니다. [AMB98] 이러한 가정에서는 구성원 함수 사용 방법에 대한 경계를 정확히 정의합니다.
  11. 모든 동시성 문제. 동시성은 많은 개발자에게 있어 새롭고 복잡한 개념이지만 경험이 풍부한 프로그래머는 이미 알고 있는 복잡한 개념입니다. 결론은 Java의 동시 프로그래밍 기능을 사용하는 경우 해당 내용을 완전히 문서화해야 한다는 것입니다. [LEA97]에서는 클래스가 동기화 및 비동기화 구성원 함수를 모두 포함하는 경우 구성원 함수가 의존하는 실행 컨텍스트를 문서화해야 한다고 제안합니다. 이는 특히 다른 개발자가 해당 구성원 함수를 안전하게 사용할 수 있도록 제한적이지 않은 액세스 권한이 필요한 경우에 해당됩니다. Runnable 인터페이스를 구현하는 클래스의 Setter(필드를 갱신하는 구성원 함수)가 동기화되지 않는 경우 해당 이유를 문서화해야 합니다. 마지막으로, 구성원 함수를 대체하거나 오버로드하고 해당 동기화를 변경하는 경우에도 그 이유를 문서화해야 합니다.
  12. 문서화는 코드 명확성을 추가하는 경우에만 수행해야 합니다. 일부 요소는 특정 구성원 함수에만 적용되므로 각각의 모든 구성원 함수에 대해 위에서 설명한 모든 요소를 문서화하지는 않습니다. 그러나 그 중 몇 가지는 작성하는 각 구성원 함수에 대해 문서화합니다.

3.4.2    내부 문서화

구성원 함수 문서화 이외에도, 해당 작업에 대해 설명하는 주석을 구성원 함수에 포함해야 합니다. 이는 구성원 함수를 보다 쉽게 이해, 유지보수 및 강화할 수 있도록 하기 위한 것입니다.

코드 내부를 문서화하기 위해 사용해야 하는 주석 유형은 C 스타일 주석( /* 및 */ )과 단일행 주석( // )이 있습니다. 앞에서 설명한 것처럼 코드의 비즈니스 로직을 문서화하기 위한 주석 스타일과 불필요한 코드를 주석 처리하기 위한 주석 스타일은 신중히 선택해야 합니다. 단일행 주석의 경우 전체 주석 행과 코드 행 끝에 표시되는 인라인 주석 모두에 사용할 수 있으므로 비즈니스 로직에 사용하는 것이 좋습니다. C 스타일 주석의 경우 한 번의 주석으로 여러 행을 쉽게 처리할 수 있으므로 불필요한 코드 행을 문서화하는 데 사용됩니다. 또한 C 스타일 주석과 문서화 주석은 그 모양이 유사하므로 함께 사용할 경우 혼동할 수 있어 코드를 이해하기가 어렵습니다. 따라서 두 주석은 반드시 필요한 경우에만 사용합니다.

내부적으로는 항상 다음 내용을 문서화해야 합니다.

  1. 제어 구조. 비교 명령문 및 루프와 같은 각 제어 구조에 대해 설명합니다. 해당 기능을 판별하기 위해 제어 구조의 모든 코드를 읽을 필요는 없으며 구조 대신 바로 앞에 표시되는 한두 행의 주석만 보면 됩니다.
  2. 코드의 수행 기능 및 해당 이유. 코드만 보고도 해당 기능을 파악할 수 있지만 코드가 명확하지 않은 경우 해당 이유를 파악하기가 어렵습니다. 예를 들어, 한 코드 행만 읽고도 총 주문액의 5% 할인율이 적용된다는 사실을 쉽게 파악할 수 있습니다. 그러나 문제는 해당 할인율이 적용되는 이유를 알 수 없다는 것입니다. 이러한 경우 할인율을 적용하는 특정 비즈니스 규칙이 반드시 존재하므로 해당 비즈니스 규칙 내용을 코드에 표기하여 다른 개발자가 코드 수행 이유를 이해할 수 있도록 해야 합니다.
  3. 로컬 변수. 이 내용은 5장에서 자세히 설명하지만 구성원 함수에 정의된 각 로컬 변수는 해당 코드 행에서 선언되어야 하며 일반적으로 해당 용도에 대해 설명하는 인라인 주석이 필요합니다.
  4. 어렵거나 복잡한 코드. 코드를 재작성할 수 없거나 시간이 없는 경우 구성원 함수에 복잡한 코드를 모두 문서화해야 합니다. 일반 규칙은 코드가 명확하지 않은 경우 문서화해야 한다는 것입니다.
  5. 처리 순서. 정의된 순서대로 실행해야 하는 명령문이 코드에 있는 경우, 이 내용을 문서화해야 합니다. [AMB98]. 간단한 코드 수정 작업 후 코드가 작동하지 않아 문제점을 파악했을 때 순서가 잘못된 경우보다 나쁜 경우는 없습니다.
  6. 닫기 중괄호 문서화. 일반적으로 제어 구조는 여러 제어 구조가 중첩되어 있습니다. 이러한 방법이 올바른 코드 작성 방법은 아니지만 경우에 따라서는 이러한 코드 작성이 보다 효과적일 수 있습니다. 문제는 닫기 중괄호 } 문자가 어느 제어 구조에 속하는지 명확하지 않다는 것입니다. 이러한 경우를 위해 일부 코드 편집기에서는 열기 중괄호를 선택할 때 자동으로 해당 닫기 중괄호가 강조표시되는 기능을 지원합니다. 그러나 모든 편집기가 이러한 기능을 지원하는 것은 아닙니다. 이때, 닫기 중괄호를 //end if, //end for//end switch와 같은 인라인 주석으로 표시하면 코드를 보다 쉽게 이해할 수 있습니다.

3.5    정확한 코드 작성 기법

이 섹션에서는 전문 개발자와 해커를 구분할 수 있는 다음과 같은 몇 가지 기법에 대해 설명합니다.

3.5.1    코드 문서화 

코드를 문서화할 필요가 없다면 보존할 가치도 없는 것입니다. [NAG95] 이 문서에서 제안하는 문서화 표준과 가이드라인을 올바르게 적용함으로써 코드 품질을 현저히 향상시킬 수 있습니다.

3.5.2    코드의 단락 나누기 또는 들여쓰기 

구성원 함수를 읽기 쉽게 작성하는 방법 중 하나는 코드의 단락을 나누거나, 다시 말해 코드 블록 범위 내에서 코드를 들여쓰기하는 것입니다. 중괄호({}) 내부의 모든 코드는 하나의 블록을 형성합니다. 기본적인 방법은 블록 내 코드를 동일하게 한 단위씩 들여쓰기하는 것입니다.

Java 규칙에서는 열기 중괄호를 행에서 블록 소유자 다음에 배치하고 닫기 중괄호를 한 레벨 들여쓰기하도록 권장합니다. 중요한 것은 [LAF97]의 지적사항처럼 조직에서 들여쓰기 스타일을 선택하고 해당 스타일을 준수해야 한다는 것입니다. Java 개발 환경에서 생성되는 코드에 대해 사용하는 것과 동일한 들여쓰기 스타일을 사용합니다.

3.5.3    코드에 공백 사용 

Java 코드에 몇 줄의 빈 행(공백이라고 함)을 추가하면 코드가 작고 쉽게 요약할 수 있는 섹션으로 분할되어 읽기 쉬워질 수 있습니다. [VIS96]에서는 제어 구조와 같은 논리 코드 그룹은 한 줄의 빈 행을 사용하여 분리하고 구성원 함수 정의는 두 줄의 빈 행을 사용하여 분리하도록 제안합니다. 이러한 공백이 없으면 코드를 읽고 이해하기가 매우 어렵습니다.

3.5.4    30초 규칙 준수 

자신이 작성한 구성원 함수를 다른 프로그래머가 보고 30초 안에 해당 기능과 그 이유 및 방법까지 완전히 이해할 수 있어야 합니다. 그렇지 못한 경우 유지보수하기가 어려워 코드를 개선해야 합니다. 이것이 바로 30초 규칙입니다. 일반적으로 구성원 함수의 길이는 한 화면보다 길어서는 안됩니다.

3.5.5    짧은 한 줄 명령행 작성 

코드는 한 줄에 한 가지 기능을 작성해야 합니다. 펀치 카드를 사용하던 시대에는 한 줄 코드에 가능한 여러 기능을 입력하는 것이 올바른 방법이었습니다. 그러나 한 줄의 코드에서 여러 기능을 수행하려는 경우 코드를 이해하기가 어렵습니다. 또한 코드를 쉽게 이해할 수 있어야 유지보수 및 강화 작업도 쉽게 수행할 수 있습니다. 각 구성원 함수가 한 가지 기능만 수행하는 것처럼 한 줄의 코드에서는 한 가지 기능만 수행해야 합니다.

또한 한 화면에서 전체 코드를 확인할 수 있도록 작성해야 합니다. [VIS96]. 인라인 주석을 사용하는 코드를 포함하여, 전체 코드 행을 읽기 위해 편집 창을 오른쪽으로 스크롤해서는 안됩니다.

3.5.6    연산 순서 지정 

코드를 보다 쉽게 이해할 수 있도록 작성하는 방법은 괄호(둥근 괄호라고도 함)를 사용하여 Java 코드 내에서의 정확한 연산 순서를 지정하는 것입니다. [NAG95], [AMB98]. 소스 코드를 이해하기 위해 언어에 대한 연산 순서를 알아야 한다면 그 자체가 심각한 문제입니다. 이는 대부분의 경우 개발자 본인과 다른 비교식 모두에 있어 논리 비교의 문제입니다. 이 문제는 앞에서 제안한 대로 짧은 한 줄 명령행을 사용함으로써 해결할 수 있습니다.


4    필드 및 특성 표준

여기서 사용하는 필드라는 용어는 BDK에서 특성을 호출하는 필드를 의미합니다. [DES97]. 필드는 오브젝트 또는 클래스에 대해 설명하는 데이터입니다. 필드는 문자열 또는 float와 같은 기본 데이터 유형이거나 고객 또는 은행 계정과 같은 오브젝트일 수 있습니다.

4.1    필드 이름 지정

필드 이름을 지정할 때는 완전한 영어 설명자를 사용하여 필드의 내용을 명확히 작성해야 합니다. [GOS96], [AMB98]. 배열 또는 벡터와 같은 콜렉션 필드에는 해당 복수 값을 나타내는 복수형 이름을 사용해야 합니다.

예제:

firstName

zipCode

unitPrice

discountRate

orderItems

4.1.1    컴포넌트 (위지트(widget)) 이름 지정

컴포넌트(인터페이스 위지트(widget)) 이름의 경우에는 전체 영어 설명자에 위지트(widget) 유형을 접두부로 추가해야 합니다. 이를 통해 컴포넌트의 목적 및 해당 유형을 쉽게 식별할 수 있으며 목록에서 각 컴포넌트를 쉽게 찾을 수 있습니다. 많은 비주얼 프로그래밍 환경에서는 모든 컴포넌트 목록을 애플릿 또는 응용프로그램으로 제공하므로 모든 컴포넌트의 이름이 button1, button2와 같은 형태로 지정되는 경우 혼동될 수 있습니다.

예제:

okButton

customerList

fileMenu

newFileMenuItem

4.1.1.1    컴포넌트 이름 지정 대안: 헝가리안 표기법 

"헝가리안 표기법" [MCO93]은 xEeeeeeEeeeee 방식을 사용하여 필드 이름을 지정해야 한다는 원칙을 기반으로 합니다. 여기서, x는 컴포넌트 유형을 나타내고 EeeeeEeeeee는 전체 영어 설명자입니다.

예제:

pbOk

lbCustomer

mFile

miNewFile

이 방법의 가장 큰 장점은 C++ 코드에 대한 공통 산업 표준이므로 많은 사용자가 이미 이 표준을 따르고 있다는 것입니다. 변수 이름의 경우 개발자는 해당 유형 및 사용 방법을 빠르게 판단할 수 있습니다. 가장 큰 단점은 접두부 표기법이 되는 것입니다.

4.1.1.2    컴포넌트 이름 지정 대안: 접미사-헝가리안 표기법 

이 표기법은 기본적으로 서로 다른 두 대안의 조합으로서, okPb, customerLb, fileMnewFileMi와 같은 이름이 생성됩니다. 가장 큰 장점은 컴포넌트 이름이 위지트(widget) 유형을 나타내고 동일한 유형의 위지트(widget)가 영문자 목록에 함께 그룹화되지 않는다는 것입니다. 반면에 가장 큰 단점은 전체 영어 설명이 아닌 명사 파생어를 사용하여 표준을 기억하기가 어렵다는 것입니다.

4.1.1.3    컴포넌트 이름 표준 설정 

어떤 규칙을 선택하더라도 "공식" 위지트(widget) 이름의 목록을 작성해야 합니다. 예를 들어, 단추 이름을 지정하는 경우, Button, PushButton, b 또는 pb를 사용할 수 있습니다. 따라서 해당 목록을 작성하여 조직 내 모든 Java 개발자가 사용할 수 있도록 해야 합니다.

4.1.2    상수 이름 지정

Java에서는 상수(변경되지 않는 값)가 일반적으로 클래스의 static final 필드로서 구현됩니다. 일반적으로 사용되는 규칙은 전체 영어 단어를 모두 대문자로 표기하고 단어 사이에 밑줄을 표시하는 것입니다. [GOS96].

예제:

MINIMUM_BALANCE

MAX_VALUE

DEFAULT_START_DATE

이 규칙의 가장 큰 장점은 상수와 변수를 쉽게 구분할 수 있다는 것입니다. 이 문서 후반부에서 상수를 정의하지 않고 대신 상수 값을 리턴하는 Getter 구성원 함수를 정의하여 코드의 유연성 및 유지보수성을 현저히 향상시킬 수 있는 방법에 대해 설명합니다.

4.1.3    콜렉션 이름 지정

배열 또는 벡터와 같은 콜렉션에는 배열이 저장하는 오브젝트 유형을 나타내는 복수형 이름을 부여해야 합니다. 이 이름은 전체 영어 설명자여야 하며 첫 번째 단어 이외의 모든 단어의 첫 번째 문자는 대문자를 사용해야 합니다.

예제:

customers

orderItems

aliases

이 규칙의 가장 큰 장점은 복수 값을 나타내는 필드(콜렉션)와 단수 값을 나타내는 필드(콜렉션이 아님)를 쉽게 구분할 수 있다는 것입니다.

4.2    필드 가시성

protected 필드가 선언되는 경우, 서브클래스에 직접 액세스하는 구성원 함수가 있어 클래스 계층 구조 내 결합력이 향상될 수 있습니다. 이러한 경우 클래스 유지보수 및 강화 작업을 수행하기가 어려우므로 이 방법을 사용해서는 안됩니다. 필드는 직접 액세스해서는 안되며 대신 액세서 구성원 함수(아래 참조)를 사용해야 합니다.

가시성 설명 올바른 사용법
public public 필드는 다른 오브젝트 또는 클래스의 다른 구성원 함수로 액세스할 수 있습니다. public 필드는 작성하지 않습니다.
protected protected 필드는 구성원 함수가 선언된 클래스의 해당 함수 또는 해당 클래스의 서브클래스에 정의된 구성원 함수로 액세스할 수 있습니다. protected 필드는 작성하지 않습니다.
private private 필드는 서브클래스가 아닌 구성원 함수가 선언된 클래스의 구성원 함수로만 액세스할 수 있습니다. 모든 필드는 Getter 및 Setter 구성원 함수(액세서)로 액세스하는 private 필드여야 합니다.

지속적이지 않은 필드(영구 저장영역에 저장되지 않는 필드)의 경우, static 또는 transient로 표시해야 합니다. [DES97]. 이러한 표시는 BDK 규칙을 준수하기 위한 것입니다.

4.2.1    이름을 "숨기지" 않음 

이름 숨기기는 로컬 변수, 인수 또는 필드 이름을 상위 범위의 해당 이름과 동일하거나 유사하게 지정하는 방법을 의미합니다. 예를 들어, 필드 이름이 firstName인 경우 firstName 로컬 변수 또는 매개변수를 작성하지 않고 firstNames 또는 firstName과 같은 이와 유사한 이름도 사용하지 않습니다. 이러한 이름을 사용하는 경우 코드를 이해하기 어려울 뿐만 아니라, 해당 개발자 또는 다른 개발자가 코드 수정 시 코드를 잘못 읽어 감지하기 어려운 오류가 발생하여 버그까지 발생할 수 있습니다.

4.3    필드 문서화

모든 필드는 다른 개발자가 이해할 수 있도록 올바르게 문서화되어야 합니다. 필요한 문서화 내용은 다음과 같습니다.

  1. 해당 설명. 다른 사용자가 사용 방법을 이해할 수 있도록 필드에 대해 설명해야 합니다.
  2. 모든 관련 불변사항. 필드의 불변사항은 항상 충족되어야 하는 조건입니다. 예를 들어, dayOfMonth 필드에 대한 불변사항은 올바른 값 범위가 1 - 31이라는 것입니다. 이 불변사항을 적용함으로써 보다 복잡한 결과가 발생할 수도 있지만 필드 값을 월과 연도를 기반으로 제한합니다. 필드 값에 대한 제한사항을 문서화함으로써 코드 원리를 보다 쉽게 이해할 수 있는 중요한 비즈니스 규칙을 정의할 수 있습니다.
  3. 예제. 복잡한 비즈니스 규칙이 연관된 필드의 경우, 이해를 도울 수 있는 몇 가지 예제 값을 제공해야 합니다. 예제는 잘 그려진 그림처럼 긴 설명보다 많은 정보를 제공할 수 있습니다.
  4. 동시성 문제. 동시성은 많은 개발자에게 있어 새롭고 복잡한 개념이지만 경험이 풍부한 동시 프로그래머는 이미 알고 있는 복잡한 개념입니다. 결론은 Java의 동시 프로그래밍 기능을 사용하는 경우 해당 내용을 완전히 문서화해야 한다는 것입니다.
  5. 가시성 결정. 필드를 private으로 선언하지 않은 경우, 해당 이유를 문서화해야 합니다. 필드 가시성은 앞의 4.2, 필드 가시성 섹션에서 설명했으며 다음 4.4, 액세서 구성원 함수 사용 섹션에서 액세서 구성원 함수를 사용한 캡슐화 지원에 대해 설명합니다. 결론적으로 private 변수를 선언하지 않은 타당한 이유가 있습니다.

4.4    액세서 구성원 함수 사용

이름 지정 규칙 뿐만 아니라 액세서 구성원 함수(필드를 갱신하거나 해당 값에 액세스하는 기능을 제공하는 구성원 함수)를 올바르게 사용하여 필드의 유지보수성을 향상시킬 수도 있습니다. 액세서 구성원 함수의 유형으로는 Setter(Mutator라고도 함)와 Getter가 있습니다. Setter는 변수 값을 수정하고 Getter는 해당 값을 확보합니다.

액세서 구성원 함수는 코드에 오버헤드를 추가하기 위해 사용되었지만 Java 컴파일러가 해당 용도에 맞게 최적화되어 있으므로 더 이상 적용되지 않습니다. 액세서를 사용하면 클래스의 구현 세부사항을 쉽게 숨길 수 있습니다. 변수가 액세스하는 최대 두 개의 제어점(Setter와 Getter)을 제공함으로써 변경해야 하는 위치를 최소화하여 클래스 유지보수성을 향상시킬 수 있습니다. Java 코드의 최적화에 대해서는 9.3, Java 코드 최적화 섹션에서 설명합니다.

조직이 강제 실행할 수 있는 가장 중요한 표준 중 하나는 액세서를 사용하는 것입니다. 일부 개발자는 약간의 키 입력 작업을 더 수행해야 한다는 이유로 액세서 구성원 함수를 사용하지 않으려고 합니다. 실제로, getter의 경우 필드 이름 앞과 뒤에 "get"과 "()"를 입력해야 합니다. 그러나 중요한 점은 액세서를 사용함으로써 얻을 수 있는 유지보수성 및 확장성 효과가 입력 작업의 번거로움을 충분히 보상한다는 것입니다.

액세서에서만 필드에 액세스할 수 있습니다. 올바른 액세서 구성원 함수 사용과 관련된 핵심 개념은 필드 관련 작업을 직접 수행할 수 있는 구성원 함수는 액세서 구성원 함수 뿐이라는 것입니다. 물론 필드가 정의된 클래스의 구성원 함수에 속하는 private 필드에 직접 액세스할 수도 있지만 private 필드의 경우 클래스 내 결합력이 증가하므로 사용하지 않는 것이 좋습니다.

4.4.1    액세서를 사용하는 이유 

"올바른 프로그램 디자인은 불필요하거나 의도하지 않거나 원하지 않는 외부 영향으로부터 프로그램 파트를 분리시키는 것입니다. 액세스 수정자(액세서)는 언어로 이러한 접촉을 제어할 수 있는 명시적이고 확인 가능한 방법을 제공합니다." [KAN97]

액세서 구성원 함수는 다음과 같은 방법으로 클래스의 유지보수성을 향상시킵니다.

  1. 필드 갱신. 각 필드를 단일 지점에서 갱신함으로써 쉽게 수정하고 테스트할 수 있습니다. 즉, 필드가 캡슐화됩니다.
  2. 필드 값 얻기. 필드 액세스 방법과 액세하는 사용자를 완전히 제어할 수 있습니다.
  3. 상수 값 및 클래스 이름 얻기. 해당 값/이름이 변경될 때 상수 및 클래스 이름 값을 Getter 구성원 함수에서 캡슐화함으로써 상수/이름이 사용되는 모든 코드 행이 아닌 Getter에서만 값을 갱신하면 됩니다.
  4. 필드 초기화. 초기화 지연을 사용함으로써 필드가 항상 초기화되지 않고 필요할 때만 초기화되도록 할 수 있습니다.
  5. 서브클래스와 해당 서브클래스 간의 결합력 완화. 서브클래스가 해당 액세서 구성원 함수만을 통해 상속 필드에 액세스하는 경우, 해당 서브클래스에 영향을 주지 않고 수퍼 클래스에서 필드 구현을 변경할 수 있으며 이를 통해 상호 결합력이 완화됩니다. 액세서는 수퍼 클래스의 변경사항이 해당 서브클래스 전체에 영향을 주는 "취약한 기본 클래스"의 위험성을 줄입니다.
  6. 필드 변경사항 캡슐화. 하나 이상의 필드와 관련된 비즈니스 규칙이 변경되는 경우, 잠재적으로 액세서를 수정하여 변경 전과 동일한 기능을 제공함으로써 새 비즈니스 규칙에 보다 쉽게 대응할 수 있습니다.
  7. 동시성 문제 단순화. [LEA97]에서는 해당 필드 값을 기반으로 하는 대기가 있는 경우 Setter 구성원 함수가 notifyAll을 포함할 단일 위치를 제공함을 지적합니다. 이를 통해 동시 솔루션을 보다 쉽게 수행할 수 있습니다.
  8. 이름 숨기기에 따른 문제 완화. 이름 숨기기 방법을 사용해서는 안되지만 로컬 변수에 필드와 동일한 이름을 제공하는 경우, 액세서를 사용한 필드 액세스는 로컬 변수에 원하는 임의의 이름을 부여할 수 있음을 의미합니다. 이 경우 필드에 직접 액세스하지 않으므로 필드 이름 숨기기에 대해 걱정하지 않아도 됩니다.

4.4.1.1    액세서를 사용하지 않는 경우 

액세서를 사용하지 않는 경우는 실행 시간이 가장 중요한 경우 뿐입니다. 그러나 이러한 경우는 응용프로그램 내 결합력이 증가해도 이 조치를 수행할 수 있는 극히 드문 경우입니다.

4.4.2    액세서 이름 지정

필드가 부울(true 또는 false)을 나타내지 않는 경우 Getter 구성원 함수 이름을 "get" + 필드 이름으로 지정한 다음 Getter 이름을 "is" + 필드 이름으로 지정해야 합니다. Setter 구성원 함수 이름은 필드 유형에 관계 없이 "set" + 필드 이름으로 지정해야 합니다([GOS96] 및 [DES97]). 필드 이름은 항상 대소문자를 혼합 사용하며 모든 단어의 첫 번째 문자는 대문자를 사용합니다. 이 이름 지정 규칙은 JDK에서 일관되게 사용되며 Bean 개발을 위해 필요합니다.

예제:

필드 유형 Getter 이름 Setter 이름
firstName
문자열
getFirstName()
setFirstName()
address
주소 
오브젝트
getAddress()
setAddress()
persistent
boolean
isPersistent()
setPersistent()
customerNo
int
getCustomerNo()
setCustomerNo()
orderItems
 
OrderItem
오브젝트
배열
getOrderItems()
 
setOrderItems()
 

 

4.4.3    고급 액세서 기법

액세서는 인스턴스 필드 값을 가져오고 설정하는 것 이상의 용도로 사용할 수 있습니다. 이 섹션에서는 다음과 같이 액세서를 사용하여 코드 유연성을 향상시킬 수 있는 방법에 대해 설명합니다.

4.4.3.1    초기화 지연 

변수는 액세스하기 전에 초기화되어야 합니다. 학계에서는 초기화에 대한 두 가지 의견이 있습니다. 즉, 오브젝트가 작성될 때 모든 변수를 초기화(기존 방식)하거나 처음 사용할 때 초기화하는 것입니다. 

첫 번째 접근 방식은 오브젝트가 처음 작성될 때 호출되는 특수 구성원 함수(생성자)를 사용합니다. 이 방식은 효과적이기는 하지만 오류가 자주 발생합니다. 새 변수를 추가하는 경우, 프로그래머가 생성자 갱신 작업을 잊고 수행하지 않을 수 있습니다.

다른 접근 방식은 초기화 지연으로서, 다음과 같이 해당 Getter 구성원 함수가 필드를 초기화하는 방법입니다. 이때 Getter 구성원 함수에서 Setter 구성원 함수를 사용하는 방법에 유의해야 합니다. 구성원 함수는 분기 번호가 0인지 확인하여 0인 경우 해당 기본값으로 설정합니다.

/** Answers the branch number, which is the leftmost

four digits of the full account number.

Account numbers are in the format BBBBAAAAAA.

*/

protected int getBranchNumber()

{

if ( branchNumber == 0)

{

// The default branch number is 1000, which

// is the main branch in downtown Bedrock.

setBranchNumber(1000);

}

return branchNumber;

}

초기화 지연은 일반적으로 데이터베이스에 저장된 실제 다른 오브젝트인 필드에 사용합니다. 예를 들어, 새 인벤토리 항목을 작성하는 경우, 기본값으로 설정한 데이터베이스에서 인벤토리 항목 유형을 패치하지 않아도 됩니다. 대신 초기화 지연을 사용하여 처음 액세스할 때 이 값을 설정합니다. 이러한 경우 필요할 때만 데이터베이스에서 인벤토리 항목 유형 오브젝트를 읽으면 됩니다.  

이 접근 방식은 정기적으로 액세스하지 않는 필드가 있는 오브젝트에만 효과적으로 사용할 수 있습니다. 불필요한 상황에서 영구 저장영역 검색에 따른 오버헤드를 발생시킬 필요는 없습니다.

초기화 지연을 Getter 구성원 함수에서 사용하는 경우, 위의 예제와 같이 해당 기본값을 사용하는 이유를 문서화해야 합니다. 이러한 문서화 작업을 수행하는 경우, 코드에서의 필드 사용 방법을 명확히 표시함으로써 유지보수성과 확장성을 모두 향상시킬 수 있습니다.

4.4.3.2    상수 액세서

일반 Java 용어로는 상수 값을 static final 필드로 구현하는 것입니다. 이러한 접근 방식으로 "상수"의 안정성을 확보할 수 있습니다. 예를 들어, Boolean 클래스는 해당 클래스의 두 가지 인스턴스를 나타내는 두 가지 static final 필드(TRUEFALSE)를 구현합니다. 이 방법은 일반적으로 해당 값이 변경되지 않는 DAYS_IN_A_WEEK 상수에도 효과적입니다.

그러나 많은 비즈니스 "상수"는 비즈니스 규칙의 변경에 따라 함께 변경됩니다. 예를 들어, ABC(Archon Bank of Cardassia) 은행의 경우 계정 유형에 관계 없이 이자가 발생하는 최소 잔액은 $500입니다. 이를 구현하려면 이자를 계산하는 구성원 함수에 사용할 static 필드 MINIMUM_BALANCE를 Account 클래스에 추가해야 합니다. 이 방법은 가능하기는 하지만 유연성이 부족한 방법입니다. 즉, 비즈니스 규칙이 변경되어 저축성 예금 계정의 최소 잔액은 $500이고 당좌 예금 계정의 최소 잔액은 $200인 경우 문제가 발생합니다. 또한 비즈니스 규칙이 변경되어 첫 번째 연도의 최소 잔액은 $500이지만 이후 1년 단위로 $400, $300 식으로 최소 잔액이 변경되는 경우에도 문제가 발생합니다. 또 다른 경우로 여름과 겨울의 최소 잔액이 각각 $500, $250로 변경될 수도 있습니다. 앞으로도 이러한 모든 규칙의 조합이 구현되어야 할 것입니다.

여기서 중요 사실은 필드로서의 상수 구현이 유연성 면에서 효과적이지 않다는 점입니다. 보다 올바른 솔루션은 상수를 Getter 구성원 함수로 구현하는 것입니다. 위의 예제에서, static 클래스 구성원 함수인 getMinimumBalance()가 static 필드 MINIMUM_BALANCE보다 훨씬 더 유연합니다. 이 구성원 함수 및 서브클래스에서 다양한 유형의 계정에 대한 다양한 비즈니스 규칙을 구현할 수 있기 때문입니다.

/** Get the value of the account number. Account numbers are in the following 
    format: BBBBAAAAAA, where BBBB is the branch number and 
    AAAAAA is the branch account number.
*/
public long getAccountNumber()
{
	return ( ( getBranchNumber() * 100000 ) + getBranchAccountNumber() );
}
/**
	Set the account number. Account numbers are in the following 
	format: BBBBAAAAAA where BBBB is the branch number and
	AAAAAA is the branch account number.
*/
public void setAccountNumber(int newNumber)
{
	setBranchAccountNumber( newNumber % 1000000 );
	setBranchNumber( newNumber / 1000000 );
}

상수 Getter의 또 다른 장점은 코드의 일관성이 향상된다는 점입니다. 예를 들어, 위의 코드의 경우 올바른 기능을 수행한다고 볼 수 없습니다. 계정 번호는 분기 번호와 분기 계정 번호의 연결 구조입니다. 코드 테스트 결과, Setter 구성원 함수인 setAccountNumber()가 분기 계정 번호를 올바르게 갱신하지 않는 것을 밝혀졌습니다. 즉, 맨 왼쪽 숫자가 네 자리 수가 아닌 세 자리 수입니다. 이는 branchAccountNumber 필드를 추출하기 위해 100,000 대신 1,000,000을 사용했기 때문입니다. 다음과 같이 이 값에 단일 소스(상수 Getter getAccountNumberDivisor())를 사용했다면 코드가 보다 일관적이고 올바르게 작동했을 것입니다.

/**
	Returns the divisor needed to separate the branch account number from the 
	branch number within the full account number. 
	Full account numbers are in the format BBBBAAAAAA.
*/
public int getAccountNumberDivisor()
{
	return ( (long) 1000000);
}
/**
	Get the value of the account number. Account numbers are in the following 
	format: BBBBAAAAAA, where BBBB is the branch number and 
	AAAAAA is the branch account number.
*/
public long getAccountNumber()
{
	return ( ( getBranchNumber() * getAccountNumberDivisor() ) + getBranchAccountNumber() );
}
/**
	Set the account number. Account numbers are in the following 
	format: BBBBAAAAAA where BBBB is the branch number and
	AAAAAA is the branch account number.
*/
public void setAccountNumber(int newNumber)
{
	setBranchAccountNumber( newNumber % getAccountNumberDivisor() );

	setBranchNumber( newNumber / getAccountNumberDivisor() );
}

상수 액세서를 사용하면 버그 발생 가능성이 낮아지고 동시에 시스템 유지보수성은 향상됩니다. 계정 번호의 레이아웃이 변경되고 이러한 변경 사실을 미리 알 수 있는 경우, 계정 번호를 빌드하거나 분할하는 데 필요한 정보를 숨기고 한 곳으로 집중시켰기 때문에 코드를 보다 쉽게 변경할 수 있습니다.

4.4.3.3    콜렉션 액세서

액세서의 가장 주된 목적은 필드에 대한 액세스를 캡슐화하여 코드 내 결합력을 완화하는 것입니다. 배열 및 벡터와 같은 콜렉션은 단일 값 필드보다 더 복잡하므로 일반적으로 콜렉션에 대한 표준 Getter 및 Setter 구성원 함수의 구현 이상을 수행해야 합니다. 특히 콜렉션에 오브젝트를 추가하거나 제거할 수 있으므로 해당 기능을 수행할 액세서 구성원 함수가 포함되어야 합니다. 가능한 경우 콜렉션 필드에 대한 다음 액세서 구성원 함수를 추가합니다.

구성원 함수 유형 이름 지정 규칙 예제
콜렉션 Getter
getCollection()
getOrderItems()
콜렉션 Setter
setCollection() 
setOrderItems()
콜렉션에 오브젝트 삽입
insertObject()
insertOrderItem()
콜렉션에서 오브젝트 삭제
deleteObject()
deleteOrderItem()
새 오브젝트 작성 및 콜렉션에 추가
newObject()
newOrderItem()

이 접근 방식의 장점은 콜렉션이 완전 캡슐화되어 나중에 다른 구조(예: 링크된 목록 또는 B-tree)로 바꿀 수 있다는 것입니다.

4.4.3.4    여러 필드에 동시 액세스

액세서 구성원 함수의 장점 중 하나는 비즈니스 규칙을 효과적으로 강제 실행할 수 있다는 것입니다. 예를 들어, 쉐이프의 클래스 계층 구조를 고려할 수 있습니다. Shape의 각 서브클래스에서는 두 가지 "xPositionyPosition" 필드를 사용하여 해당 위치를 알고 있으며, 구성원 함수 move(Float xMovement, Float yMovement)를 호출하여 2차원 평면의 화면에서 이동할 수 있습니다. 여기서, 쉐이프가 한 번에 하나의 축을 따라 이동하는 것은 바람직하지 않습니다. 대신, x 축과 y 축을 따라 동시에 이동합니다. move() 구성원 함수에 대한 매개변수로서 0.0 값을 전달할 수는 있습니다. 즉, move() 구성원 함수는 public 함수여야 하지만 setXPosition()setYPosition() 구성원 함수는 모두 private 함수로서, move() 구성원 함수로 호출될 수 있어야 합니다.

대체 구현으로는 다음과 같이 두 필드를 한 번에 갱신하는 Setter 구성원 함수를 사용할 수 있습니다. 구성원 함수 setXPosition()setYPosition()은 계속 private 함수이므로 외부 클래스 또는 서브클래스에서 직접 호출할 수 없습니다. 이 함수를 직접 호출해서는 안된다는 내용의 정보가 다음에 제공됩니다.

/** Set the position of the shape */
protected void setPosition(Float x, Float y)
{
	setXPosition(x);
	setYPosition(y);
}
/** Set the x position.  Important: Invoke setPosition(), not this member function. */
private void setXPosition(Float x)
{
	xPosition = x;
}
/** Set the y position of the shape
    Important: Invoke setPosition(), not this member function.
*/
private void setYPosition(Float y)
{
	yPosition = y;
}

4.5    액세서 가시성

액세서를 protected 유형으로 작성해야 서브클래스만 필드에 액세스할 수 있습니다. "외부 클래스"가 필드에 액세스해야 하는 경우에만 해당 Getter 또는 Setter를 public 유형으로 작성합니다. 일반적으로는 Getter 구성원 함수가 public 함수가 되고 Setter 함수는 protected 함수가 됩니다.

경우에 따라 특정 불변사항을 충족시키기 위해 private Setter를 작성해야 하는 경우가 있습니다. 예를 들어, Order 클래스에는 OrderItem 인스턴스의 콜렉션을 나타내는 필드와 전체 주문 총계를 나타내는 두 번째 orderTotal 필드가 포함될 수 있습니다. orderTotal은 주문 항목의 합계 또는 모든 하위 총계를 나타내는 편리 필드입니다. orderTotal 값을 갱신해야 하는 구성원 함수는 주문 항목의 콜렉션을 조작하는 함수뿐입니다. 해당 구성원 함수가 모두 Order에서 구현되는 것으로 가정하면 getOrderTotal()이 public에 가까운 경우라도 setOrderTotal()을 private으로 작성해야 합니다.

4.6    항상 정적 필드 초기화

정적 필드는 클래스 필드라고도 하며, 정적 필드에 액세스하기 전에는 클래스 인스턴스가 작성될 수 없으므로 올바른 값을 부여해야 합니다.

 


5    로컬 변수 표준

로컬 변수는 블록 범위에 정의되는 오브젝트 또는 데이터 항목으로서 구성원 함수도 여기에 포함됩니다. 로컬 변수의 범위는 변수가 정의되는 블록입니다. 로컬 변수에 대한 중요한 코딩 표준은 다음에 초점을 맞춥니다.

5.1    로컬 변수 이름 지정

일반적으로 로컬 변수의 이름은 필드에 사용되는 규칙과 동일한 규칙에 따라 지정됩니다. 즉, 전체 영어 설명자를 사용하고 첫 번째 단어 이외의 모든 단어의 첫 번째 문자는 대문자를 사용합니다.

그러나 사용자 편의를 위해 다음과 같은 특정 로컬 변수 유형에는 이 이름 지정 규칙이 유연하게 적용됩니다.

5.1.1    스트림 이름 지정

단일 입력 및/또는 출력 스트림을 열고 사용한 후 구성원 함수로 닫은 경우, 일반 규칙은 해당 스트림 이름에 각각 InOut을 사용하는 것입니다. [GOS96]. 입력 및 출력 모두에 사용된 스트림의 경우, inOut이라는 이름을 사용합니다.

이 이름 지정 규칙에 대한 일반적인 대안은 Sun의 권장사항과는 충돌하더라도 In, OutinOut 대신 각각 inputStream, outputStreamioStream을 사용하는 것입니다.

5.1.2    루프 카운터 이름 지정

루프 카운터는 로컬 변수에 일반적으로 사용되며, C/C++에서도 사용할 수 있어 Java 프로그래밍에서는 루프 카운터에 대해 i, j 또는 k를 사용할 수 있습니다. [GOS96]. 루프 카운터에 이러한 이름을 사용하는 경우, 일관되게 사용합니다.

일반적인 대안은 loopCounter 또는 간단하게 counter와 같은 이름을 사용하는 것이지만, 이러한 접근 방식의 문제점은 두 개 이상의 카운터가 필요한 구성원 함수에서 counter1counter2와 같은 이름이 자주 사용된다는 것입니다. 즉, i, j, k가 카운터 기능을 수행한다는 점입니다. 이러한 이름은 입력하기도 쉽고 일반적으로 허용되는 이름입니다.

5.1.3    예외 오브젝트 이름 지정

예외 처리 또한 Java 코딩에서 매우 일반적이므로 일반 예외에 문자 e를 사용할 수 있습니다. [GOS96].

5.2    로컬 변수 선언 및 문서화

Java에서는 다음과 같이 여러 가지 규칙을 사용하여 로컬 변수를 선언하고 문서화할 수 있습니다.

  1. 코드 행당 하나의 로컬 변수를 선언합니다. 이 규칙은 코드 행당 하나의 명령문을 지정하는 것과 같으며 인라인 주석을 사용하여 각 변수를 문서화할 수 있습니다.
  2. 인라인 주석을 사용하여 로컬 변수를 문서화합니다. 인라인 주석은 단일 행 스타일 주석으로서, 먼저 동일한 코드 행에 //가 표시되고 그 바로 다음에 명령이 표시됩니다. 인라인 주석은 엔드라인 주석이라고도 합니다. 이 주석은 로컬 변수의 용도, 적합한 사용 위치 및 사용 이유에 대해 문서화해야 하며 이를 통해 코드를 쉽게 이해할 수 있습니다.
  3. 로컬 변수는 한 가지 목적으로만 사용합니다. 로컬 변수를 여러 가지 목적으로 사용하는 경우, 응집성이 약화되어 이해하기 어렵습니다. 또한 코드 앞 부분에 있는 로컬 변수의 이전 값의 예상치 않은 부작용으로 인해 코드에 버그가 발생할 수 있습니다. 물론 로컬 변수를 재사용하는 경우 메모리가 적게 할당되어 보다 효율적이지만 결과적으로 코드의 유지보수성이 저하되어 코드 상태가 취약해집니다. 즉, 메모리 절감에 따른 손실이 더 크다고 할 수 있습니다.

5.2.1    선언에 대한 일반 주석

해당 코드를 처음 사용하는 사용자의 경우 코드 행 간, 예를 들어 if 문 범위 내에서 선언된 로컬 변수를 쉽게 찾을 수 없습니다.

로컬 변수를 처음 사용하기 바로 직전에 선언하는 방법 중 하나는 코드 맨 위에서 선언하는 것입니다. 구성원 함수는 짧게 작성해야 하므로(3.5.5, 짧은 한 줄 명령행 작성 참조), 로컬 변수에 대한 정보를 얻기 위해 코드 맨 위로 이동할 수 있습니다.


6    구성원 함수에 대한 매개변수 표준

구성원 함수에 대한 매개변수 및 인수에 중요한 표준은 이름 지정 방법과 문서화 방법입니다. 매개변수는 구성원 함수 인수를 나타낼 때 사용됩니다.

6.1    매개변수 이름 지정

매개변수 이름은 로컬 변수에 사용되는 것과 동일한 규칙에 따라 지정되어야 합니다. 따라서 로컬 변수와 같이, 이름 숨기기 문제를 고려해야 합니다.

예제:

customer

inventoryItem

photonTorpedo

e

스몰토크(Smalltalk)를 사용한 올바른 대안은 로컬 변수에 대한 이름 지정 규칙을 사용하고 이름 앞에 "a" 또는 "an"을 추가하는 것입니다. "a" 또는 "an"을 추가함으로써 매개변수와 로컬 변수 및 필드가 뚜렷이 구분되어 이름 숨기기 문제점을 피할 수 있으므로 선호되는 접근 방식입니다.

예제:

aCustomer

anInventoryItem

aPhotonTorpedo

anInputStream

anException

6.2    매개변수 문서화

구성원 함수에 대한 매개변수는 javadoc @param 태그를 사용하여 구성원 함수에 대한 헤더 문서에서 문서화되며 다음과 같은 내용을 설명해야 합니다.

  1. 매개변수의 기능. 다른 개발자가 매개변수 사용 방법에 대한 전체 컨텍스트를 이해할 수 있도록 매개변수의 기능를 문서화해야 합니다.
  2. 제한 조건 또는 전제 조건. 구성원 함수가 매개변수에 대한 전체 값 범위를 허용할 수 없는 경우, 해당 구성원 함수의 호출자에게 해당 사실을 알려야 합니다. 일반적으로 구성원 함수는 양수 또는 5자 미만의 문자열만 허용합니다.
  3. 예제. 매개변수의 기능이 명확하지 않는 경우, 문서화 내용에 하나 이상의 예제를 제공해야 합니다.

6.2.1    매개변수 유형에 따른 인터페이스 사용

매개변수 유형에 Object와 같은 클래스를 지정하는 대신, 가능한 경우 Runnable과 같은 인터페이스를 지정합니다. 이러한 접근 방식은 상황에 따라 보다 구체적이거나(Runnable이 Object보다 구체적임) 잠재적으로 다형성을 보다 효율적으로 지원할 수 있습니다. 매개변수를 특정 클래스 계층 구조에 속하는 클래스의 인스턴스가 아닌, 특정 인터페이스를 지원하는 매개변수로 지정할 수 있습니다. 이러한 경우 필요한 기능에 대한 다형성 기준만 충족시키면 됩니다.


7    클래스, 인터페이스, 패키지 및 컴파일 단위 표준

이 장에서는 클래스, 인터페이스, 패키지 및 컴파일 단위에 대한 표준과 가이드라인에 대해 집중 설명합니다. 클래스는 오브젝트가 이로부터 인스턴스화(작성)되는 템플리트입니다. 클래스에는 필드 및 구성원 함수에 대한 선언이 포함됩니다. 인터페이스는 구성원 함수 및 필드를 모두 포함하여, 인터페이스를 구현하는 클래스가 지원해야 하는 공통 서명에 대한 정의입니다. 패키지는 관련 클래스의 콜렉션입니다. 마지막으로 컴파일 단위는 클래스 및 인터페이스가 선언되는 소스 코드 파일입니다. Java에서는 컴파일 단위를 데이터베이스에 저장할 수 있으므로 개별 컴파일 단위가 실제 소스 코드와 직접 관련되지 않을 수 있습니다.

7.1    클래스 표준

클래스에 중요한 표준은 다음과 같은 규칙을 기반으로 합니다.

7.1.1    클래스 이름 지정

표준 Java 규칙에서는 전체 영어 설명자를 사용하며 첫 번째 문자는 대문자로 시작하고 나머지 이름 문자는 대소문자를 함께 사용합니다([GOS96] 및 [AMB98]).

클래스 이름은 단수형이어야 합니다.

예제:

Customer

Employee

Order

OrderItem

FileStream

String

7.1.2    클래스 문서화

다음 정보는 문서화 주석에서 클래스 정의 바로 앞에 표시되어야 합니다.

  1. 클래스 목적. 개발자가 클래스의 일반 목적을 알아야 해당 클래스가 원하는 요구를 충족시키는지 여부를 판별할 수 있습니다. 항상 클래스에 대한 유용한 정보(예: 패턴의 일부 여부 또는 관련 제한사항의 존재 여부)를 문서화하는 습관을 가져야 합니다. [AMB98].
  2. 알려진 버그. 클래스와 관련하여 해결되지 않은 문제점이 있는 경우, 이를 문서화하여 다른 개발자가 클래스의 단점과 문제를 이해할 수 있도록 해야 합니다. 버그를 수정하지 않는 이유 또한 문서화해야 합니다. 버그가 단일 구성원 함수에만 해당되는 경우, 대신 구성원 함수와 직접 연관되어야 합니다.
  3. 클래스의 개발 또는 유지보수 히스토리. 일반적으로 클래스 변경 날짜, 작성자 및 변경사항 요약을 나열하는 히스토리 테이블을 포함해야 합니다. 유지보수 프로그래머는 이 히스토리를 보고 과거 클래스 수정사항을 파악하며 클래스 변경사항 및 해당 변경 작업자를 문서화합니다.
  4. 관련 불변사항 문서화. 불변사항은 "항상" 충족되어야 하는 인스턴스 또는 클래스에 대한 검증 세트입니다. 여기서 "항상"이라는 의미는 오브젝트 또는 클래스에 대해 구성원 함수가 호출되기 전과 구성원 함수가 호출된 직후로 정의됩니다. [MEY88]. 클래스의 불변사항을 문서화함으로써 다른 개발자에게 클래스 사용 방법에 대한 소중한 정보를 제공할 수 있습니다.
  5. 동시성 전략. Runnable 인터페이스를 구현하는 모든 클래스는 해당 동시성 전략을 모두 설명해야 합니다. 동시 프로그래밍은 많은 프로그래머에게 새롭고 복잡한 주제이므로 다른 프로그래머가 기존 작업을 이해할 수 있도록 충분한 시간을 투자해야 합니다. 동시성 전략의 내용과 해당 전략을 선택한 이유에 대해 문서화해야 합니다. 일반 동시성 전략 [LEA97]에는 다음 요소가 포함됩니다.
  • 동기화된 오브젝트
  • 실패(balking) 오브젝트
  • 보호 오브젝트
  • 버전 오브젝트
  • 동시성 정책 제어기
  • 승인자

7.1.3    클래스 선언

클래스를 이해하기 위해 만드는 방법 중 하나는 일관된 방식으로 선언하는 것입니다. Java에서는 일반적으로 다음과 같은 순서로 클래스를 선언합니다.

  • public 구성원 함수
  • public 필드
  • protected 구성원 함수
  • protected 필드
  • private 구성원 함수
  • private 필드

[LAF97]에서는 생성자와 finalize()를 먼저 나열해야 한다고 주장합니다. 일반적으로 다른 개발자가 클래스 사용 방법을 이해하기 위해 확인하는 첫 번째 구성원 함수이기 때문입니다. 또한 모든 필드를 private으로 선언하는 표준이 있으므로 실제 선언 순서는 다음과 같습니다.

생성자

finalize()

public 구성원 함수

protected 구성원 함수

private 구성원 함수

private 필드

각 구성원 함수 그룹에서는 일반적으로 영문자 순서로 나열합니다. 많은 개발자들은 각 그룹에 static 구성원 함수를 맨 처음 나열한 다음 인스턴스 구성원 함수를 나열하며 마지막으로 이 두 하위 그룹 각각의 내부에 구성원 함수를 영문자 순서대로 나열합니다. 이 두 가지 접근 방식은 모두 올바른 방식이므로 한 가지를 선택하여 계속 사용하면 됩니다.

7.1.4    public 및 protected 인터페이스 최소화

객체 지향 디자인의 기본 원칙 중 하나는 클래스의 public 인터페이스를 최소화하는 것입니다. 이 원칙에는 다음과 같은 이유가 있습니다.

  1. 학습 용이. 해당 public 인터페이스만 이해하면 클래스 사용 방법을 배울 수 있습니다. 따라서 public 인터페이스가 작을수록 클래스를 쉽게 배울 수 있습니다.
  2. 결합력 완화. 클래스 인스턴스가 다른 클래스 인스턴스로 또는 클래스로 직접 메시지를 보낼 때마다 두 클래스가 서로 결합됩니다. public 인터페이스의 최소화는 결합 기회의 최소화를 의미합니다.
  3. 우수한 유연성. 결합력과 직접적인 관련이 있는 사항입니다. public 인터페이스의 구성원 함수가 구현되는 방법을 변경하려는 경우(일반적으로 구성원 함수가 리턴하는 결과를 수정하려는 경우) 구성원 함수를 호출하는 코드를 잠재적으로 수정해야 합니다. public 인터페이스가 작을수록 캡슐화 기능이 향상되고 결과적으로 유연성 또한 향상됩니다.

public 인터페이스 최소화는 올바른 작업이지만 protected 인터페이스 최소화의 경우에는 명확하지 않습니다. 일반적으로 서브클래스 관점에서 볼 때 모든 해당 수퍼 클래스의 protected 인터페이스는 실제로 public 인터페이스이기 때문입니다. protected 인터페이스의 모든 구성원 함수는 서브클래스로 호출할 수 있습니다. 따라서 public 인터페이스를 최소화하려는 이유와 동일한 이유로 클래스의 protected 인터페이스를 최소화합니다.

7.1.4.1    public 인터페이스 우선 정의

경험이 풍부한 개발자는 대부분 코딩을 시작하기 전에 먼저 클래스의 public 인터페이스를 정의합니다.  

7.2    인터페이스 표준

인터페이스에 중요한 표준은 다음과 같은 규칙을 기반으로 합니다.

7.2.1    인터페이스 이름 지정

Java 규칙에서는 대소문자를 혼합 사용하고 각 단어의 첫 번째 문자에 대문자를 사용하여 인터페이스 이름을 지정합니다. 인터페이스 이름 지정을 위해 선호되는 Java 규칙은 Singleton 또는 DataInput과 같이 일반적인 설명 명사 대신 Runnable 또는 Cloneable과 같은 설명 형용사를 사용하는 것입니다. [GOS96].

7.2.1.1    대체

인터페이스 이름에 문자 "I"를 접두부로 추가합니다. [COA97]의 제안 내용대로, 인터페이스 이름 앞쪽에 문자 "I"를 추가하면 ISingleton 또는 IRunnable과 같은 이름이 생성됩니다. 이 접근 방식을 사용하면 인터페이스 이름과 클래스 및 패키지 이름을 쉽게 구분할 수 있습니다. 이러한 잠재적인 이름 지정 규칙은 클래스 다이어그램(오브젝트 모델이라고도 함)을 보다 쉽게 읽을 수 있다는 점에서 선호됩니다. 이러한 방식의 단점은 Runnable과 같은 기존 인터페이스의 이름을 이 접근 방식을 사용하여 지정해야 한다는 것입니다. 이 인터페이스 이름 지정 규칙은 Microsoft의 COM/DCOM 아키텍처에도 사용할 수 있습니다.

7.2.2    인터페이스 문서화

다음 정보는 문서화 주석에서 인터페이스 정의 바로 앞에 표시되어야 합니다.

  1. 인터페이스의 목적. 다른 개발자가 인터페이스를 사용하기 전에 내포하고 있는 개념을 이해해야 합니다. 즉, 해당 목적을 이해해야 합니다. 인터페이스를 정의해야 하는지 여부에 대한 올바른 테스트는 해당 목적을 쉽게 설명할 수 있는지 여부입니다. 쉽게 설명할 수 없는 경우, 인터페이스를 시작하지 않아도 됩니다. 인터페이스 개념은 Java에서 새로운 개념이므로 개발자가 올바른 사용 방법에 대해 잘 알지 못하며 단지 새로운 기능이라는 이유만으로 남용할 수 있습니다.
  2. 인터페이스 사용 및 사용 금지 방법. 개발자는 인터페이스 사용 방법은 물론 사용 금지 방법까지 이해해야 합니다. [COA97].

구성원 함수에 대한 서명은 인터페이스에 정의되므로, 사용자는 각 구성원 함수 서명에 대해 3 장에서 설명하는 구성원 함수 문서화 규칙을 따라야 합니다.

7.3    패키지 표준

패키지에 중요한 표준은 다음과 같은 규칙을 기반으로 합니다.

  • 이름 지정 규칙
  • 문서화 규칙

7.3.1    패키지 이름 지정

이름 지정 패키지와 연관된 몇 가지 규칙은 다음과 같습니다.

  1. 식별자는 마침표로 분리됩니다. Sun에서는 패키지 이름을 보다 쉽게 읽으려면 패키지 이름의 ID를 마침표로 분리하도록 제안합니다. 예를 들어, 패키지 이름 java.awt는 두 개의 ID, 즉 javaawt로 구성됩니다.
  2. Sun의 표준 Java 분배 패키지는 ID "java"로 시작됩니다. Sun은 Java 개발 환경 벤더에 관계 없이 일관된 방식으로 표준 Java 패키지의 이름을 지정할 수 있도록 이 권한을 보유해 왔습니다.
  3. 로컬 패키지 이름은 대소문자가 혼합된 ID로 시작됩니다. 로컬 패키지는 조직에서 내부적으로 사용되며 다른 조직에 분배되지 않습니다. 이러한 패키지 이름의 예제로는 persistence.mapping.relational interface.screens가 포함됩니다.
  4. 글로벌 패키지 이름은 사용자 조직을 위해 예약된 인터넷 도메인 이름으로 시작됩니다. 여러 조직에 분배될 패키지에는 원래 조직의 도메인 이름이 포함되어야 하며 최상위 레벨 도메인 유형은 대문자를 사용해야 합니다. 예를 들어, 이전 패키지를 분배하려면 해당 이름을 com.rational.www.persistence.mapping.relationalcom.rational.www.interface.screens으로 지정합니다.

7.3.2    패키지 문서화

조직에서 개발한 패키지의 목적에 대해 설명하는 하나 이상의 외부 문서를 유지보수해야 합니다. 각 패키지에 대해 다음 사항을 문서화해야 합니다.

  1. 패키지에 대한 기본 설명. 다른 개발자가 패키지에 대한 모든 정보를 알아야 사용 여부를 결정할 수 있으며 공유 패키지의 경우 강화 또는 확장 여부를 결정할 수 있습니다.
  2. 패키지의 클래스. 다른 개발자가 패키지의 포함 내용에 대해 알 수 있도록 패키지의 클래스 및 인터페이스 목록과 각각에 대한 간략한 온라인 설명을 포함합니다.

: 패키지 이름을 사용하여 HTML 파일을 작성하고 해당 패키지 디렉토리에 저장합니다. 이 파일의 확장자는 .html입니다.

7.4    컴파일 단위 표준

컴파일 단위에 대한 표준 및 가이드라인은 다음 규칙을 기반으로 합니다.

7.4.1    컴파일 단위 이름 지정

컴파일 단위(이 경우 소스 코드 파일)에는 내부에서 선언되는 기본 클래스 또는 인터페이스의 이름이 부여되어야 합니다. 파일 이름에는 패키지 또는 클래스와 동일한 이름과 동일한 대소문자를 사용합니다. 파일 이름에는 확장자 .java를 추가해야 합니다.

예제:

Customer.java

Singleton.java

SavingsAccount.java

7.4.2    컴파일 단위 문서화

파일당 하나의 클래스 또는 인터페이스만 선언하는 것이 바람직하지만 경우에 따라서는 동일한 파일에 여러 클래스(또는 인터페이스)를 정의할 수 있습니다. 일반 규칙은 클래스 B의 유일한 목적이 클래스 A에서만 필요한 기능의 캡슐화인 경우 클래스 A와 동일한 소스 코드 파일에 클래스 B가 표시될 수 있다는 것입니다. 결과적으로 클래스 뿐만 아니라 소스 코드 파일에 다음과 같은 문서화 규칙이 적용됩니다.

  1. 클래스가 여러 개인 파일의 경우, 각 클래스를 나열합니다. 파일에 클래스가 여러 개 있는 경우, 클래스 목록과 각 클래스에 대한 간략한 설명을 제공해야 합니다.
  2. 파일 이름 및/또는 식별 정보. 파일 이름은 파일 맨 위에 포함되어야 합니다. 이렇게 하면 코드가 인쇄될 때 코드의 소스 파일을 확인할 수 있습니다.
  3. 저작권 정보. 필요한 경우, 파일에 대한 저작권 정보를 표시해야 합니다. 일반적으로는 저작권 연도와 저작권을 소유하고 있는 개인 또는 조직의 이름을 표시합니다. 코드 작성자는 저작권 소유자가 아닙니다.

8    오류 처리 및 예외

일반적인 방법은 논리 및 프로그래밍 오류, 구성 오류, 손상된 데이터, 자원 부족 등 오류에만 예외를 사용하는 것입니다. 일반 규칙은 정상 조건과 오버로드 또는 하드웨어 실패가 없는 경우 예외가 발생해서는 안된다는 것입니다.

  1. 예외는 논리 및 프로그래밍 오류, 구성 오류, 손상된 데이터 및 자원 부족을 처리하기 위해 사용합니다

예외는 발생 지점을 포함하여 가능한 빨리 적합한 로깅 메커니즘을 사용하여 보고합니다.

  1. 특정 추상에서 내보내는 예외 수를 최소화합니다.

대규모 시스템의 경우, 각 레벨에서 여러 예외를 처리하면 코드를 읽고 유지보수하기가 어렵습니다. 이러한 경우 예외 처리가 정상 처리를 방해할 수 있습니다.

예외 수를 최소화하기 위한 몇 가지 방법은 다음과 같습니다.

  • 예외는 소수만 내보내고, 발생한 문제점의 본질에 대한 자세한 정보는 결함 추상 또는 잘못된 오브젝트 조회를 허용하는 "diagnosis" 기본요소를 제공합니다.
  • 오브젝트에 "예외" 상태를 추가하고 오브젝트의 유효성을 명시적으로 검사하는 기본요소를 제공합니다.
  1. 자주 발생하며 예상할 수 있는 이벤트에는 예외를 사용하지 않습니다.

명확한 오류가 아닌 조건을 나타내는데 예외를 사용하면 다음과 같은 몇 가지 불편사항이 발생합니다.

  • 혼동을 줍니다.
  • 일반적으로, 이해 및 유지보수가 어려운 제어 플로우에서 혼란이 가중됩니다.
  • 대부분의 소스 레벨 디버거는 기본적으로 모든 예외를 표시하므로 코드를 디버그하기가 매우 어렵습니다.

예를 들어, 검색의 Value_Not_Found와 같이 함수에서 리턴된 예비 값의 양식으로서 예외를 사용하지 않습니다. out 매개변수가 포함된 프로시저를 사용하거나 Not_Found를 의미하는 특수 값을 사용하거나 레코드의 리턴된 유형을 판별식 Not_Found로 압축합니다.

  1. 제어 구조를 구현하기 위해 예외를 사용하지 않습니다.

이는 예외를 goto 문의 양식으로 사용해서는 안된다는 이전 규칙의 특수한 경우입니다.

  1. 상태 코드의 값이 올바른지 확인합니다.

서브프로그램에서 리턴한 상태 코드를 out 매개변수로 사용하는 경우, 항상 이 매개변수를 서브프로그램 본문의 첫 번째 실행 가능 명령문으로 작성하여 out 매개변수에 값을 지정하십시오. 체계적으로 모든 상태를 기본적으로 성공 또는 실패로 작성하십시오. 예외 핸들러를 포함하여 가능한 모든 서브프로그램 종료 방법을 고려하십시오.

  1. 안전 점검은 클라이언트가 아닌 로컬로 수행하십시오.

올바른 입력이 제공되지 않아 서브프로그램에서 오류 출력이 생성되는 경우, 올바르지 않은 입력을 제어된 방식으로 감지하고 보고하는 코드를 서브프로그램에 설치합니다. 클라이언트에게 올바른 값을 전달하도록 지시하는 주석에 의존하지 마십시오.. 해당 주석은 곧 무시되고, 올바르지 않은 매개변수가 감지되지 않는 경우 디버그하기 어려운 오류가 발생합니다.


9    기타 표준 및 문제

이 장에서는 중요한 표준 및 가이드라인에 대해 설명합니다. 각 표준과 가이드라인은 매우 중요하여 각각의 내용만으로도 하나의 장을 구성할 수 있습니다.

9.1    재사용

사용자가 직접 구매하거나 외부 소스에서 재사용하는 Java 클래스 라이브러리 또는 패키지는 100% 순수 Java로서 인증을 받아야 합니다. [SUN97]. 이 표준을 강제 실행함으로써 재사용하는 내용이 앞으로 배치될 모든 플랫폼에서 작동할 수 있음을 보증할 수 있습니다. Java 클래스, 패키지 또는 애플릿은 Java 라이브러리를 전문적으로 사용하는 써드파티 개발 회사나 사용자 조직 내 다른 부서 또는 프로젝트 팀 등 다양한 소스에서 얻을 수 있습니다.

9.2    클래스 가져오기

import 문을 사용하면 와일드 카드를 사용하여 클래스 이름을 표시할 수 있습니다. 예를 들어, 다음과 같습니다.

import java.awt.*;

이 명령은 java.awt 패키지의 모든 클래스를 가져오는 명령이지만 실제로는 그렇지 않습니다. 즉, java.awt 패키지에서 사용자가 사용하는 모든 클래스는 컴파일될 때 코드로 가져옵니다. 사용하지 않는 클래스는 가져오지 않습니다. 이 기능은 좋은 기능처럼 보이지만 실제로는 코드를 읽기 어렵게 합니다. 보다 나은 방법은 코드에서 사용하는 클래스의 이름을 완전히 규정하는 것입니다([LAF97], [VIS96]). 클래스를 가져오기 위한 보다 효과적인 방법은 다음 예제를 참조하십시오.

import java.awt.Color
import java.awt.Button
import java.awt.Container

9.3    Java 코드 최적화

코드 최적화는 프로그래머가 고려할 마지막 사항으로서 최우선 사항은 아닙니다. 코드는 필요한 코드만 최적화하면 되므로 최적화 문제는 마지막에 처리하면 됩니다. 코드의 극히 일부분이 처리 시간에 큰 영향을 미치는 경우가 있는데 이러한 코드를 최적화하면 됩니다. 경험이 부족한 프로그래머가 흔히 하는 실수 중 하나가 실제 코드 실행 속도가 빠른 경우에도 모든 코드를 최적화하려는 경우입니다.

  1. 아무도 신경 쓰지 않는 코드의 최적화에 시간을 낭비하지 않습니다.

코드 최적화 시 가장 먼저 고려해야 할 사항은 [KOE97]에서 설명하는 대로 대규모 입력에 대한 안정적인 오버헤드 및 성능입니다. 그 이유는 간단합니다. 즉, 소규모 입력을 위한 런타임 속도는 안정적인 오버헤드를 통해 제어할 수 있고 대규모 입력은 알고리즘으로 제어할 수 있기 때문입니다. Koenig은 소규모 및 대규모 입력에 모두 올바르게 작동하는 프로그램이 중간 규모 입력에도 올바르게 작동할 수 있다고 주장합니다.

다양한 하드웨어 플랫폼 및/또는 운영 체제에서 작동하는 소프트웨어를 작성해야 하는 개발자는 다양한 플랫폼의 각 특성을 잘 이해해야 합니다. 메모리 및 버퍼 처리 방법과 같이 특정 시간이 소요되는 오퍼레이션은 일반적으로 플랫폼마다 상당한 차이를 보입니다. 일반적으로는 플랫폼에 따라 코드를 다르게 최적화해야 합니다.

코드 최적화와 관련하여 고려해야 할 또 다른 문제는 사용자의 우선순위입니다. 사용자별로 컨텍스트에 따라 특정 지연에 민감한 반응을 보일 수 있기 때문입니다. 예를 들어, 사용자는 5초 동안 데이터를 로드한 다음에 화면을 표시하는 것보다 화면을 즉시 표시하고 8초 동안 데이터를 로드하는 것을 더 선호합니다. 즉, 대부분의 사용자는 즉각적인 피드백만 제공된다면 조금 더 기다리는 것은 그다지 중요하게 생각하지 않습니다. 이는 코드를 최적화하는 데 있어 중요한 지식입니다.

  1. 사용자가 시각적으로 최적화 상태로 느낄 수 있도록 코드를 빠르게 실행하지 않아도 됩니다.

최적화가 응용프로그램 성공 또는 실패의 기준이 될 수는 있지만 무엇보다 중요한 것은 코드가 올바르게 작동하도록 하는 것입니다. 즉, 속도는 느리지만 올바르게 작동하는 소프트웨어가 속도는 빠르지만 올바르게 작동하지 않은 소프트웨어보다 우수한 소프트웨어입니다.

9.4    Java 테스트 하니스 작성

객체 지향 테스트는 매우 중요한 주제임에도 불구하고 객체 개발 커뮤니티에서 거의 무시되어 왔습니다. 그러나 선택한 작업 언어에 관계 없이 누군가는 작성한 소프트웨어를 테스트해야 합니다. 테스트 하니스는 구성원 함수의 콜렉션으로서, 일부는 클래스 자체에 임베드되어 있고(자체 테스트) 일부는 특수 테스트 클래스에 포함되어 응용프로그램을 테스트하는 데 사용됩니다.

  1. 모든 테스트 구성원 함수의 이름에는 접두부 "test"를 추가합니다. 이 접두부를 보고 코드의 모든 테스트 구성원 함수를 쉽게 찾을 수 있습니다. 테스트 구성원 함수 이름에 접두부 "test"를 추가하는 데 따른 이점은 프로덕션 버전을 컴파일하기 전에 소스 코드에서 구성원 함수를 쉽게 테스트할 수 있다는 점입니다.
  2. 모든 구성원 함수 테스트 구성원 함수의 이름은 일관되게 지정합니다. 메소드 테스트는 단일 구성원 함수가 정의된 대로 수행되는지 검증하는 작업입니다. 모든 구성원 함수 테스트 구성원 함수의 이름은 "testMemberFunctionNameForTestName" 형식에 따라 지정해야 합니다. 예를 들어, withdrawFunds()를 테스트하기 위한 테스트 하니스 구성원 함수에는 testWithdrawFundsForInsufficientFunds() testWithdrawFundsForSmallWithdrawal()이 포함됩니다. withdrawFunds()에 대한 일련의 테스트를 수행하는 경우, 모든 테스트를 호출하는 구성원 함수인 testWithdrawFunds()를 작성할 수 있습니다.
  3. 모든 클래스 테스트 구성원 함수의 이름은 일관되게 지정합니다. 클래스 테스트는 단일 클래스가 정의된 대로 수행되는지 검증하는 작업입니다. 모든 클래스 테스트 구성원 함수의 이름은 "testSelfForTestName" 형식에 따라 지정해야 합니다(예: Account 클래스를 테스트하기 위한 테스트 하니스 구성원 함수 testSelfForSimultaneousAccess()testSelfForReporting()).
  4. 클래스 테스트를 호출하는 단일 지점을 작성합니다. 모든 클래스 테스트 및 메소드 테스트 구성원 함수를 호출하는 static 구성원 함수인 testSelf()를 개발합니다.
  5. 테스트 하니스 구성원 함수를 문서화합니다. 테스트 하니스 구성원 함수를 문서화합니다. 문서화 내용에는 테스트에 대한 설명과 예상 테스트 결과가 포함되어야 합니다.

10    성공 패턴

표준 문서를 작성하는 것만으로 유능한 개발자가 되는 것은 아닙니다. 유능한 개발자가 되기 위해서는 보다 생산적인 개발자가 되어야 하며 이는 곧 해당 표준을 효과적으로 적용해야 함을 의미합니다.

10.1    효과적인 패턴 사용

다음 내용은 이 문서에서 설명하는 Java 코딩 표준 및 가이드라인을 보다 효과적으로 사용할 수 있도록 도와주는 정보입니다.

  1. 표준을 이해합니다. 각 표준과 가이드라인을 통해 생산성 향상 효과를 얻을 수 있는 이유를 이해해야 합니다. 예를 들어, 가이드라인에서 지시하는 내용이라도 행마다 각 로컬 변수를 선언해서는 안됩니다. 변수를 선언하여 코드를 쉽게 이해할 수 있음을 확신할 때 이를 수행해야 합니다.
  2. 표준과 가이드라인을 신뢰합니다. 각 표준을 이해하는 것부터 시작해야 하지만 무엇보다 먼저 해당 내용을 신뢰해야 합니다. 표준을 따른다는 것은 반드시 그래야 하기 때문이 아니라 본인 스스로 가장 효과적인 코딩 방법이라는 믿음을 갖고 있기 때문이어야 합니다.
  3. 표준 및 가이드라인은 나중이 아닌 코딩 시점에서 직접 수행해야 합니다. 문서화된 코드는 코드를 작성할 때나 작성한 후 보다 쉽게 이해할 수 있습니다. 구성원 함수 및 필드 이름을 일관되게 지정함으로써 개발 및 유지보수 작업을 모두 쉽게 수행할 수 있습니다. 코드가 분명하면 개발 및 유지보수 작업을 모두 쉽게 수행할 수 있습니다. 즉, 표준을 따르면 코드 개발 및 유지보수 작업 모두에서 코드를 쉽게 사용할 수 있어 본인의 생산성 뿐만 아니라 유지보수 개발자의 생산성까지 향상될 수 있습니다. 처음부터 코드를 올바르게 작성하면 작성하는 과정에서부터 이점을 얻을 수 있습니다.
  4. 품질 보증 프로세스의 일부로 생각합니다. 코드 검사에는 소스 코드가 조직에서 채택한 표준을 따르고 있는지 확인하는 작업이 포함되어야 합니다. 즉, 표준을 개발자의 생산성을 향상시키기 위한 훈련 및 지도 기반으로 사용합니다.

10.2    성공적인 코드 작성을 위한 기타 요인

  1. 시스템이 아닌 사람을 위한 프로그램을 작성합니다. 개발 노력의 가장 주된 목적은 다른 사용자가 쉽게 이해할 수 있는 코드를 작성하는 것입니다. 다른 사용자가 내용을 이해할 수 없는 코드는 좋은 코드가 아닙니다. 이름 지정 규칙을 사용하고 코드를 문서화하고 코드의 단락을 구분해야 합니다.
  2. 디자인한 후 코딩합니다. 프로그램에서 중요한 코드 중 일부를 변경해야 하는 경우 일반적으로 새 매개변수를 구성원 함수로 전달하거나 클래스를 여러 클래스로 나누어야 합니다. 이 경우 기존 코드와 수정된 코드의 재구성 버전이 올바르게 작동하는지 확인해야 하며 그 과정에서 만족감을 얻을 수도 있습니다. 또한 작업 과정에서 최초 개발자가 코드를 작성할 때 고려하지 않거나 실수한 점에 대해 생각해 볼 수도 있으며 디자인 작업을 먼저 수행했다면 문제가 발생하지 않을 수도 있다고 유추해 볼 수도 있을 것입니다. 즉, 실제로 코딩을 시작하기 전에 코드 작성 방법을 분석하면 실제 작성 시간을 줄일 수 있습니다. 더불어 향후 발생할 수 있는 코드 변경을 미리 생각해보는 것만으로도 해당 영향을 줄일 수 있습니다.
  3. 적은 단계로 개발합니다. 소수 구성원 함수를 작성하여 테스트한 다음 추가 구성원 함수를 작성하는 것과 같은 적은 단계를 통한 개발이 일반적으로 모든 코드를 한 번에 작성하고 나중에 수정하는 것보다 훨씬 효과적입니다. 또한 코드를 테스트하고 수정하는 경우에도 100행보다는 10행이 보다 수월합니다. 실제로, 각각 10행으로 구성되는 10개의 인크리먼트가 모인 100행 길이의 코드에 대한 프로그래밍, 테스트 및 수정 작업을 수행하는 데 소요되는 시간이 전체가 100행인 단일 코드 블록을 작성하는 시간보다 적게 소요됩니다.  
    이유는 간단합니다. 코드를 테스트하고 버그를 발견할 때 일반적으로 방금 작성한 새 코드에서 버그를 찾고 나머지 코드는 견고한 코드라고 확신하기 때문입니다. 또한 큰 코드 섹션보다는 작은 코드 섹션에서 버그를 보다 빨리 처리할 수 있습니다. 이처럼 작은 인크리먼트 단계로 개발함으로써 버그를 발견하는 데 소요되는 평균 시간을 줄이고 결과적으로 전체 개발 시간을 단축할 수 있게 됩니다.
  4. 코드는 간단하게 작성합니다. 복잡한 코드는 지적 허영심을 채워줄 수는 있겠지만 다른 사람이 이해하지 못하는 코드는 좋은 코드라고 할 수 없습니다. 버그를 수정하거나 코드를 강화하기 위해 태그를 수정해야 하는 경우 복잡한 코드라면 다른 사용자는 물론 작성자 본인까지도 코드를 재작성하게 될 가능성이 높습니다. 실제로 다른 사람이 작성한 코드를 이해할 수 없어 재작성한 경험을 대부분 갖고 있을 것입니다. 그러한 경우 코드를 재작성할 때 최초 개발자를 천재라고 생각하는 대신 바보라고 생각할 가능성이 높습니다. 나중에 재작성해야 하는 코드를 작성하는 것은 절대로 자랑할만한 일이 아니므로 코드는 최대한 간단하게 작성해야 합니다.
  5. 일반 패턴, 안티 패턴 및 관용 표현에 대해 학습합니다. 개발자의 생산성을 향상시키는 데 유용한 많은 분석, 디자인 및 프로세스 패턴과 안티 패턴은 물론 프로그래밍 관용 표현까지 존재합니다.

11    요약

이 장에서는 사용자 편의를 위해 이 문서에서 제공하는 가이드라인에 대해 요약 설명합니다. 또한 이 장에는 Java 코딩 표준이 주제별로 한 페이지 분량으로 요약되어 있습니다.

  • Java 이름 지정 규칙
  • Java 문서화 규칙
  • Java 코딩 규칙

이 백서에서 설명하는 나머지 표준 및 가이드라인을 요약하기 전에 가장 중요한 내용을 다시 한 번 반복하고자 합니다.

표준을 따르지 않는 경우 해당 내용을 문서화하십시오. 이 지침을 제외한 모든 표준은 유연하게 적용할 수 있습니다. 이러한 경우 표준을 따르지 않은 이유, 표준 불이행에 따른 잠재적 의미와 해당 상황에서 표준을 적용하기 위해 필요한 조건에 대해 문서화해야 합니다.

11.1    Java 이름 지정 규칙

아래에서 설명하는 몇 가지 예외를 제외하고는 이름 지정 시 항상 전체 영어 설명자를 사용해야 합니다. 또한 일반적으로는 소문자를 사용하되, 클래스 이름 및 인터페이스 이름의 첫 번째 문자와 중간 단어 및 마지막 단어의 첫 번째 문자에는 대문자를 사용해야 합니다.

일반 개념:

  • 전체 영어 설명자를 사용합니다.
  • 해당 분야에서 사용되는 용어를 사용합니다.
  • 이름에는 대소문자를 혼합 사용하면 쉽게 읽을 수 있습니다.
  • 약어는 되도록 사용하지 않고 반드시 필요한 경우에만 사용합니다.
  • 긴 이름은 사용하지 않습니다(15자 미만이 적합).
  • 대소문자만 다르거나 유사한 이름을 사용하지 않습니다.
  • 밑줄을 사용하지 않습니다.
항목 이름 지정 규칙 예제
인수/
매개변수
전달되는 값/오브젝트에 대한 전체 영어 설명을 사용하되, 이름의 접두부로 "a" 또는 "an"을 추가할 수 있습니다. 중요한 점은 한 가지 접근 방식을 선택하여 일관되게 사용하는 것입니다.
customer, account,
               - 또는 -
aCustomer, anAccount
필드/
필드/
특성
필드에 대한 전체 영어 설명을 사용하되, 첫 번째 문자는 소문자를 사용하고 첫 단어를 제외한 모든 단어의 첫 번째 문자는 대문자를 사용합니다.
firstName, lastName, 
warpSpeed
 
부울 Getter 구성원 함수 모든 부울 Getter에는 접두부 "is"를 추가해야 합니다. 위에서 설명한 부울 필드에 대한 이름 지정 표준을 따르는 경우, 필드 이름을 부여하면 됩니다.
isPersistent(), isString(), 
isCharacter() 
클래스 전체 영어 설명을 사용하되, 모든 단어의 첫 번째 문자는 대문자를 사용합니다.
Customer, SavingsAccount
컴파일 단위 파일 클래스 또는 인터페이스의 이름을 사용하거나, 파일의 클래스 수가 기본 클래스보다 많은 경우 끝에 ".java"를 추가하여' 소스 코드 파일임을 표시합니다.
Customer.java, 
SavingsAccount.java,
Singleton.java
컴포넌트/
위지트(widget)
컴포넌트의 용도에 대해 설명하는 전체 영어 설명을 사용하되, 컴포넌트 유형을 끝에 연결합니다.
okButton, customerList, 
fileMenu
생성자 클래스 이름을 사용합니다.
Customer(), SavingsAccount()
소멸자 Java에는 소멸자가 없지만 대신 오브젝트에 대한 가비지 콜렉션을 수행하기 전에 구성원 함수 finalize()를 호출합니다.
finalize()
예외 일반적으로 예외를 나타내는 문자 "e"를 사용할 수 있습니다.
e
최종 정적 필드(상수) 모두 대문자를 사용하고 밑줄로 단어를 분리합니다. 보다 나은 방법은 유연성을 향상시키는 final static Getter 구성원 함수를 사용하는 것입니다.
MIN_BALANCE, DEFAULT_DATE
Getter 구성원 함수 액세스하는 필드의 이름에 접두부 "get"을 추가합니다.
getFirstName(), getLastName(), 
getWarpSpeeed()
인터페이스 인터페이스가 캡슐화하는 개념에 대해 설명하는 전체 영어 설명을 사용하되, 모든 단어의 첫 번째 문자는 대문자를 사용합니다. 일반적으로 이름 뒷 부분에 "able", "ible" 또는 "er"을 추가하지만 반드시 필요하지는 않습니다.
Runnable, Contactable, 
Prompter, Singleton
로컬 변수 전체 영어 설명을 사용하되, 첫 번째 문자는 소문자를 사용하고 기존 필드/필드를 숨기지 않습니다. 예를 들어, 필드 이름이 "firstName"인 경우, 로컬 변수 이름으로 "firstName"을 사용할 수 없습니다.
grandTotal, customer, 
newAccount
루프 카운터 일반적으로 문자 i, j 또는 k를 사용하거나 counter를 이름으로 사용할 수 있습니다.
i, j, k, counter
패키지 전체 영어 설명을 사용하고 대소문자를 혼합 사용하되, 각 단어의 첫 번째 문자는 대문자를 사용하고 나머지는 모두 소문자를 사용합니다. 글로벌 패키지의 경우, 인터넷 도메인 이름의 방향을 반대로 바꾸고 패키지 이름을 연결합니다.
java.awt,
com.ambysoft.www.
persistence.mapping
구성원 함수 구성원 함수의 기능에 대한 전체 영어 설명을 사용하되, 가능한 능동태 동사로 시작하고 첫 번째 문자는 소문자를 사용합니다.
openFile(), addAccount()
Setter 구성원 함수 액세스하는 필드의 이름에 접두부 "set"을 추가합니다.
setFirstName(), setLastName(), 
setWarpSpeed()

11.2    Java 문서화 규칙

문서화와 관련하여 준수해야 하는 가장 올바른 규칙은 코드를 처음 보는 것으로 가정하여 "빠른 시간 안에 해당 코드를 효과적으로 이해하는 데 필요한 정보"가 무엇인지 생각해보는 것입니다.

일반 개념:

11.2.1    Java 주석 유형

다음 차트는 세 가지 유형의 Java 주석과 제안 사용법에 대해 설명합니다.

주석 유형 사용법 예제
문서화 문서화 주석은 문서화할 인스턴스, 클래스, 구성원 함수 및 필드에 대한 선언 바로 앞에서 사용됩니다. 문서화 주석은 javadoc(아래 참조)에서 클래스에 대한 외부 문서화를 작성하기 위해 처리됩니다. /**
Customer: A customer is any person or organization that we sell services and products to.
@author S.W. Ambler
*/
C 스타일 C 스타일 주석은 더 이상 적용되지 않지만 사용자의 마음이 바뀌는 경우에 대비하여 유지하려는 코드 행을 문서화하는 데 사용됩니다. 또는 디버깅 작업 시 일시적으로 꺼두기 위해 사용할 수도 있습니다. /*
This code was commented out by B.Gustafsson, June 4 1999 because it was replaced by the preceding code. Delete it after two years if it is still not applicable.
. . . (소스 코드)
*/
단일 행 단일 행 주석은 구성원 함수 내부에서 비즈니스 로직, 코드 섹션 및 임시 변수 선언을 문서화하는 데 사용됩니다. // Apply a 5% discount to all invoices
// over $1000 as defined by the Sarek
// generosity campaign started in
// Feb. of 1995.

11.2.2    문서화 내용

다음 차트는 사용자가 작성하는 Java 코드의 각 부분에 대해 문서화해야 하는 내용에 대해 요약 설명합니다.

항목 문서화 내용
인수/
매개변수
매개변수 유형

목적

제한 조건 및 전제 조건

예제

필드/
필드/특성
해당 설명

모든 관련 불변사항 문서화

예제

동시성 문제

가시성 결정

클래스 클래스의 목적

알려진 버그

클래스의 개발 및 유지보수 히스토리

관련 불변사항 문서화

동시성 전략

컴파일 단위 간략한 설명을 포함하여, 클래스에 정의된 각 클래스 또는 인터페이스

파일 이름 및/또는 식별 정보

저작권 정보

Getter 구성원 함수 해당되는 경우 초기화 지연 사용 이유 문서화
인터페이스 목적

사용 및 사용 금지 방법

로컬 변수 해당 용도 및 목적
구성원 함수: 문서화 함수의 기능 및 해당 이유

매개변수로서 전달해야 하는 구성원 함수

구성원 함수가 리턴하는 결과

알려진 버그

구성원 함수로 인해 발생하는 예외

가시성 결정

구성원 함수가 오브젝트를 변경하는 방법

코드 변경 히스토리 포함

필요한 경우 구성원 함수를 호출하는 방법 예제

해당 전제 조건 및 사후 조건

구성원 함수: 내부 주석 제어 구조

코드의 수행 기능 및 해당 이유

로컬 변수

어렵거나 복잡한 코드

처리 순서

패키지 패키지에 대한 기본 설명

패키지의 클래스

11.3    Java 코딩 규칙(일반)

Java 코드의 유지보수성 및 확장성과 관련하여 중요한 많은 규칙과 표준이 존재합니다. 그러나 가장 중요한 점은 시스템을 위한 프로그램이 아니라 사용자, 동료 개발자를 위한 프로그램을 작성해야 한다는 것입니다. 다른 사람이 이해할 수 있는 프로그램을 작성하는 것이 가장 중요합니다.

규칙 대상 규칙
액세서 구성원 함수 데이터베이스 필드에 대한 초기화 지연 사용 고려

모든 필드를 얻고 수정하는 데 액세서 사용

"상수"에 액세서 사용

콜렉션의 경우, 항목 삽입/추가를 위한 구성원 함수 추가

가능한 경우, public이 아닌 protected 액세서 작성

필드 필드는 항상 private으로 선언

필드에 직접 액세스하지 않고 대신 액세서 구성원 함수 사용

final static 필드(상수)를 사용하지 않고 대신 액세서 구성원 함수 사용

이름을 숨기지 않음

항상 정적 필드 초기화

클래스 public 및 protected 인터페이스 최소화

코딩 시작 전에 클래스에 대한 public 인터페이스 정의

다음과 같은 순서로 클래스의 필드 및 구성원 함수 선언

  • 생성자
  • finalize()
  • public 구성원 함수
  • protected 구성원 함수
  • private 구성원 함수
  • private 필드
로컬 변수 이름을 숨기지 않음

코드 행당 하나의 로컬 변수 선언

인라인 주석을 사용하여 로컬 변수 문서화

사용 직전에 로컬 변수 선언

로컬 변수는 한 가지 목적으로만 사용

구성원 함수 코드 문서화

코드 표시

제어 구조 앞에 한 줄의 공백 사용, 구성원 함수 선언 앞에 두 줄의 공백 사용

구성원 함수는 30초 안에 이해할 수 있어야 함

짧은 한 줄 명령행 작성

가능한 구성원 함수의 가시성 제한

연산 순서 지정


12    참조

참조 코드 참조 정보
[AMB98] Ambler, S.W. (1998). Building Object Applications That Work: Your Step-By-Step Handbook for Developing Robust Systems with Object Technology. New York: SIGS Books/Cambridge University Press.
[COA97] Coad, P. 및 Mayfield, M. (1997). Java Design: Building Better Apps & Applets. Upper Saddle River, NJ: Prentice Hall Inc.
[DES97] DeSoto, A. (1997). Using the Beans Development Kit 1.0 February 1997: A Tutorial. Sun Microsystems.
[GOS96] Gosling, J., Joy, B., Steele, G. (1996). The Java Language Specification. Reading, MA: Addison Wesley Longman Inc.
[GRA97] Grand, M. (1997). Java Language Reference. Sebastopol, CA: O. Reilly & Associates, Inc.
[KAN97] Kanerva, J. (1997). The Java FAQ. Reading, MA: Addison Wesley Longman Inc.
[KOE97] Koenig, A. (1997). The Importance--and Hazards--of Performance Measurement. New York: SIGS Publications, Journal of Object-Oriented Programming, January, 1997, 9(8), pp. 58-60.
[LAF97] Laffra, C. (1997). Advanced Java: Idioms, Pitfalls, Styles and Programming Tips. Upper Saddle River, NJ: Prentice Hall Inc.
[LEA97] Lea, D. (1997). Concurrent Programming in Java: Design Principles and Patterns. Reading, MA: Addison Wesley Longman Inc.
[MCO93] McConnell, S. (1993). Code Complete: A Practical Handbook of Software Construction. Redmond, WA: Microsoft Press.
[MEY88] Meyer, B. (1988). Object-Oriented Software Construction. Upper Saddle River, NJ: Prentice Hall Inc.
[NAG95] Nagler, J. (1995). Coding Style and Good Computing Practices. http://wizard.ucr.edu/~nagler/coding_style.html
[SUN96] Sun Microsystems (1996). javadoc - The Java API Documentation Generator. Sun Microsystems.
[SUN97] Sun Microsystems (1997). 100% Pure Java Cookbook for Java Developers: Rules and Hints for Maximizing the Portability of Java Programs. Sun Microsystems.
[VIS96] Vision 2000 CCS Package and Application Team (1996). Coding Standards for C, C++, and Java. http://v2ma09.gsfc.nasa.gov/coding_standards.html

13    용어집

100% 순수(100% pure): Java 애플릿, 응용프로그램 또는 패키지가 Java VM을 지원하는 모든 플랫폼에서 실행된다는 내용의 Sun 승인입니다.

액세서(accessor): 필드 값을 수정하거나 리턴하는 구성원 함수로서, 액세스 수정자라고도 합니다. GetterSetter를 참조하십시오.

분석 패턴(analysis pattern): 비즈니스 또는 도메인 문제점의 솔루션에 대해 설명하는 모델링 패턴입니다.

안티 패턴(antipattern): 일반 문제점 해결을 위한 접근 방식으로서, 잘못된 방법이거나 아주 효과가 없는 것으로 판명됩니다.

인수(argument): 매개변수를 참조하십시오.

BDK: Beans Development Kit

블록(block): 중괄호로 묶는 명령문의 콜렉션으로서, 명령문이 없을 수도 있습니다.

중괄호(braces): 열기({) 중괄호와 닫기(}) 중괄호가 한 쌍으로 블록의 시작과 끝을 정의하는 데 사용됩니다.

클래스(class): 오브젝트가 인스턴스화되는 정의 또는 템플리트입니다.

클래스 테스트(class testing): 클래스 또는 해당 인스턴스(오브젝트)가 정의대로 수행되는지 확인하는 조치입니다.

CMVC: Configuration Management and Version Control

컴파일 단위(compilation unit): 클래스 및 인터페이스가 선언되는 소스 코드 파일로서, 디스크에는 실제 파일 또는 데이터베이스에 저장된 "가상" 파일입니다.

컴포넌트(component): 목록, 단추 또는 창과 같은 인터페이스 위지트(widget)

상수 Getter(constant getter): "상수" 값을 리턴하는 Getter 구성원 함수로서, 필요에 따라 하드 코딩되거나 계산됩니다.

생성자(constructor): 오브젝트를 작성할 때 필요한 모든 초기화를 수행하는 구성원 함수입니다.

포함(containment): 오브젝트에는 해당 동작을 수행하기 위해 협력하는 다른 오브젝트가 포함됩니다. 이는 내부 클래스를 사용하거나(JDK 1.1+) 오브젝트 내 다른 클래스의 인스턴스를 집계하여(JDK 1.0+) 수행됩니다.

CPU: 중앙 처리 장치(Central Processing Unit)

C 스타일 주석(C-style comment): 복수행 주석을 작성하는 데 사용할 수 있는 C/C++ 언어에서 채택된 Java 주석 형식(/* 및 */)입니다. 일반적으로 테스트 과정에서 불필요하거나 원하지 않는 코드 행을 "문서화"하는 데 사용됩니다.

디자인 패턴(design pattern): 디자인 문제점의 솔루션에 대해 설명하는 모델링 패턴입니다.

소멸자(destructor): 메모리에서 더 이상 필요하지 않은 오브젝트를 제거하는 데 사용되는 C++ 클래스 구성원 함수입니다. Java는 자체 메모리를 관리하므로 이러한 유형의 구성원 함수는 필요하지 않습니다. 그러나 Java는 개념 측면에서 유사한 구성원 함수인 finalize()를 지원합니다.

문서화 주석(documentation comment): javadoc에서 클래스 파일에 대한 외부 문서화를 제공하기 위해 처리할 수 있는 Java 주석 형식(/** 및 */)입니다. 인터페이스, 클래스, 구성원 함수 및 필드에 대한 기본 문서화는 문서화 주석을 사용하여 작성해야 합니다.

필드(field): 클래스 또는 클래스 인스턴스에 대해 설명하는 변수로서 리터럴 데이터 유형 또는 다른 오브젝트입니다. 인스턴스 필드는 오브젝트(인스턴스)에 대해 설명하고 static 필드는 클래스에 대해 설명합니다. 필드는 필드, 필드 변수 및 특성이라고도 합니다.

finalize(): 오브젝트가 메모리에서 제거되기 전에 가비지 콜렉션 과정에서 자동적으로 호출되는 구성원 함수입니다. 이 구성원 함수의 목적은 열린 파일 닫기와 같은 필수 정리 작업을 수행하는 것입니다.

가비지 콜렉션(garbage collection): 더 이상 참조되지 않는 오브젝트가 자동으로 메모리에서 제거되는 자동 메모리 관리 기능입니다.

Getter: 필드 값을 리턴하는 액세서 구성원 함수의 유형입니다. Getter는 상수 값에 응답하는 데 사용할 수 있으며 일반적으로 보다 유연한 접근 방식이므로 상수를 static 필드로서 구현하는 것보다 바람직합니다.

HTML: HyperText Markup Language. 웹 페이지 작성을 위한 산업 표준 형식입니다.

들여쓰기(indenting): 코드 들여쓰기를 참조하십시오.

인라인 주석(inline comment): 코드와 동일한 행에서 코드 바로 뒤에 주석이 표시되는, 소스 코드 행을 문서화하기 위한 행 주석 사용 방법입니다. 일반적으로는 단일 행 주석을 이러한 용도로 사용하지만 C 스타일 주석도 사용할 수 있습니다.

인터페이스(interface): 구성원 함수 및 필드를 모두 포함하여, 인터페이스를 구현하는 클래스가 지원해야 하는 공통 서명에 대한 정의입니다. 인터페이스는 컴포지션을 통해 다형성을 향상시킵니다.

I/O: 입출력(I/O)

불변사항(invariant): 불변사항은 "항상" 충족되어야 하는 인스턴스 또는 클래스에 대한 검증 세트입니다. 여기서 "항상"이라는 의미는 오브젝트 또는 클래스에 대해 구성원 함수가 호출되기 전후를 의미합니다.

Java: 다양한 컴퓨팅 플랫폼에서 작동되어야 하는 응용프로그램 및 인터넷용 응용프로그램을 개발하는 데 적합한 산업 표준 객체 지향 개발 언어입니다.

javadoc: Java 소스 코드 파일을 처리하여 외부 문서를 HTML 형식으로 생성하는 JDK에 포함된 유틸리티로서, 코드 파일의 문서화 주석에 따라 소스 코드 파일의 컨텐츠를 설명합니다.

JDK: Java Development Kit

초기화 지연(lazy initialization): 필드가 처음 필요할 때 해당 Getter 구성원 함수에서 필드가 초기화되는 기법입니다. 초기화 지연은 필드가 일반적으로 필요하지 않고 대용량 메모리를 저장해야 하거나 영구 저장영역에서 읽어야 할 때 사용됩니다.

로컬 변수(local variable): 블록 범위에 정의된 변수로서 구성원 함수도 여기에 포함됩니다. 로컬 변수의 범위는 변수가 정의되는 블록입니다.

구성원 함수(member function): 클래스 또는 클래스 인스턴스와 연관된 실행 가능 코드입니다. 구성원 함수는 함수의 객체 지향 형태로 간주할 수 있습니다.

구성원 함수 서명(member function signature): 서명을 참조하십시오.

메소드 테스트(method testing): 구성원 함수가 정의대로 수행되는지 확인하는 조치입니다.

이름 숨기기(name hiding): 필드, 변수 또는 인수 이름을 상위 범위의 해당 이름과 동일하거나 유사하게 사용하는 방법을 의미합니다. 이름 숨기기를 남용하는 가장 일반적인 예는 로컬 변수 이름을 인스턴스 필드와 동일하게 지정하는 경우입니다. 이름 숨기기는 코드를 이해하기가 어려워 버그가 발생할 수 있으므로 가능한 사용하지 마십시오.

오버로드(overload): 구성원 함수가 동일한 클래스 또는 서브클래스에서 두 번 이상 정의될 때 오버로드된다고 합니다. 이때 각 정의의 서명만 다릅니다.

대체(override): 구성원 함수가 서브클래스에서 재정의되어 원래 정의와 동일한 서명을 갖는 경우 대체된다고 합니다.

패키지(package): 관련 클래스의 콜렉션입니다.

코드 단락 나누기(paragraphing): 코드 블록 외부의 코드와 해당 코드를 구분할 수 있도록 코드 블록 범위 내에서 코드를 한 단위씩(보통 가로 탭) 들여쓰기하는 기법입니다. 코드 단락 나누기를 수행하면 코드가 읽기 쉬워집니다.

매개변수(parameter): 구성원 함수로 전달된 인수로서, 매개변수는 string, int 또는 object와 같은 정의된 유형일 수 있습니다.

사후 조건(postcondition): 구성원 함수 실행이 완료된 후 충족되는 특성 또는 검증

전제 조건(precondition): 전제 조건은 구성원 함수가 올바른 기능을 수행할 수 있는 제한 조건입니다.

특성(property): 필드를 참조하십시오.

Setter: 필드 값을 설정하는 액세서 구성원 함수입니다.

서명(signature): 매개변수 유형의 조합(있는 경우)과 구성원 함수로 전달되어야 하는 해당 순서입니다. 서명은 구성원 함수 서명이라고도 합니다.

단일 행 주석(single-line comment): 비즈니스 로직의 내부 구성원 함수 문서화에 일반적으로 사용되는 C/C++ 언어에서 채택된 Java 주석 형식(//)입니다.

태그(tag): javadoc에서 전문가 수준의 주석을 생성하기 위해 처리하는 문서화 주석의 지정된 섹션을 표시하는 규칙입니다(예: @see, @author).

테스트 하니스(test harness): 코드를 테스트하기 위한 구성원 함수의 콜렉션입니다.

UML: Unified Modeling Language. 산업 표준 모델링 표기법입니다.

가시성(visibility): 클래스, 구성원 함수 또는 필드의 캡슐화 레벨을 표시하는 데 사용되는 기법입니다. 가시성은 키워드(public, protected 및 private)를 사용하여 정의할 수 있습니다.

공백(whitespace): 읽기 쉽게 하기 위해 코드에 추가되는 빈줄, 공백 및 탭입니다.

위지트(widget): 컴포넌트를 참조하십시오.