반응형
잘 구성된 자바 코드의 전체적인 체계에 대해서 알아본다.
소스 파일
자바 소스 코드를 체계적으로 이해할 수 있도록 작성하려면 클래스의 선언과 클래스 멤버들에 대한 체계적인 배치가 필요하다. 소스 파일에 코드 구성의 체계에는 여러 방법이 있을 수 있지만 잘 구성된 소스 파일은 보통 다음과 같은 순서를 가진다. 각 항목들 사이에는 반드시 빈 줄을 삽입하여 보기 좋게 만든다.
파일 머릿말 주석은 파일에 포함된 클래스 이름/버전/날짜 등과 저작권 등을 표시한다. 파일 맨 처음에 위치하므로 인덱스로서도 사용할 수 있다. 필요없으면 생략해도 된다.
import 문장들
복잡한 클래스는 여러개의 import 문장을 가지는 경우가 많다. 이런 import 문장들은 java.awt.* 처럼 패키지 전체를 import 하는 경우도 있고, java.awt.Button 처럼 개별 클래스들을 import 하는 경우도 있다. import 문장들을 체계적으로 다루려면 다음과 같은 순서로 한다.
클래스에 대한 Javadoc 주석
Javadoc 주석은 클래스에 대한 설명과 특징 등을 설명한다. 특별한 용법이나 주의사항들도 설명한다. 클래스의 버전, 저자, 참조 클래스들, 호환되는 자바 버전등을 기재한다. 예를 들면 다음과 같다.
멤버 필드들의 선언
어떤 클래스는 많은 수의 필드 멤버를 가진다. 이런 경우 체계적으로 정리되지 않으면 관리하기 어렵다. 다음과 같은 형태로 정리한다.
상수를 대문자로 표시하면 선언때뿐만이 아니라 수식같은 곳에서 사용될 때 상수임을 쉽게 알 수 있다. 다음은 java.lang.Math 클래스의 PI 상수 선언을 보여준다.
생성자들
생성자 메소드는 다른 메소드들과 달리 객체 생성과 관련이 있으므로 멤버 필드 선언 뒤에 메소드 중 제일 먼저 위치하는 것이 좋다. 다른 규칙은 메소드 선언과 같이 적용된다.
메소드들 선언
메소드에 대한 선언에는 다음과 같은 규칙을 적용하는 것이 좋다.
결론
소프트웨어 개발자들은 아마도 자신만의 코딩 스타일이 있을 것이다. 또한 언어의 발전에 따라 여러가지 코딩 스타일이 사용되어 왔다. 자신이 어떤 코딩 스타일이 좋다고 믿는 것은 큰 문제가 되지 않지만 가장 중요한 것은 역시 다른 사람에게 쉽게 이해될 수 있고 유지/보수될 수 있는 코딩 스타일이 가장 좋은 스타일이라는 점이다. 마치 가전제품에서 개발자만 좋다고 믿는 스타일보다는 소비자가 익숙한 스타일이 더 좋은 모델이듯이, 명료하고 읽기 쉬운 코딩 스타일이 좋은 코딩 스타일이라고 할 수 있다.
내 경험에 따르면 소프트웨어 개발이 끝난 뒤에 디버깅 과정과 유지/보수 과정에서 엔드 유저와 함께 코드를 검토하는 일이 빈번하다. 명료하지 못한 코드는 신뢰감을 떨어뜨리고 디버깅 및 트레이싱에도 많은 시간을 요구하게 하며, 유지/보수를 어렵게 만든다. 따라서 좋은 코딩 스타일을 평소에 몸에 익혀두는 것도 좋은 일이다.
본 글의 저작권은 이동훈에 있으며 저작권자의 허락없이 온라인/오프라인으로 본 글을 유보/복사하는 것을 금합니다.
소스 파일
자바 소스 코드를 체계적으로 이해할 수 있도록 작성하려면 클래스의 선언과 클래스 멤버들에 대한 체계적인 배치가 필요하다. 소스 파일에 코드 구성의 체계에는 여러 방법이 있을 수 있지만 잘 구성된 소스 파일은 보통 다음과 같은 순서를 가진다. 각 항목들 사이에는 반드시 빈 줄을 삽입하여 보기 좋게 만든다.
- 파일 머릿말 주석 (필요할 경우)
- 패키지 선언
- Import 문장들
- 클래스 선언/구현
- Javadoc 주석
- 클래스 선언
- 멤버 필드들의 선언
- 생성자들
- 메소드들 선언(main() 메소드 제외)
- inner 클래스들 (있을 경우)
- main() 메소드 (있을 경우)
파일 머릿말 주석은 파일에 포함된 클래스 이름/버전/날짜 등과 저작권 등을 표시한다. 파일 맨 처음에 위치하므로 인덱스로서도 사용할 수 있다. 필요없으면 생략해도 된다.
import 문장들
복잡한 클래스는 여러개의 import 문장을 가지는 경우가 많다. 이런 import 문장들은 java.awt.* 처럼 패키지 전체를 import 하는 경우도 있고, java.awt.Button 처럼 개별 클래스들을 import 하는 경우도 있다. import 문장들을 체계적으로 다루려면 다음과 같은 순서로 한다.
- 자바 표준 클래스들 (java.io.* 등 java. 으로 시작하는 패키지의 클래스들)
- 자바 확장 클래스들 (javax. 으로 시작하는 패키지의 클래스들)
- 서드-파티 제품 클래스들 (즉, 구매한 패키지 제품들의 클래스들)
- 애플리케이션 클래스들 (즉, 해당 애플리케이션을 위해 만든 클래스들)
// 자바 클래스들
import java.awt.*;
import java.awt.event*;
import java.util.*;
import javax.swing.table.*;
// .....를 위한 abc사의 bean 관련 ..... 패키지.
import com.abcbean.irt.*;
import com.abcbean.irtutil.*;
// ....를 구현하기 위한 GUI 컴포넌트들
import com.actavp.gui.*;
// 애플리케이션 클래스
import com.mycompany.util.*;
import java.awt.*;
import java.awt.event*;
import java.util.*;
import javax.swing.table.*;
// .....를 위한 abc사의 bean 관련 ..... 패키지.
import com.abcbean.irt.*;
import com.abcbean.irtutil.*;
// ....를 구현하기 위한 GUI 컴포넌트들
import com.actavp.gui.*;
// 애플리케이션 클래스
import com.mycompany.util.*;
클래스에 대한 Javadoc 주석
Javadoc 주석은 클래스에 대한 설명과 특징 등을 설명한다. 특별한 용법이나 주의사항들도 설명한다. 클래스의 버전, 저자, 참조 클래스들, 호환되는 자바 버전등을 기재한다. 예를 들면 다음과 같다.
/**
* 이 클래스는 ...을 위한 클래스다.
* 이 클래스는 ...한 경우 .... 역할을 수행한다.
* 이 클래스는 ...한 방법으로 사용될 수 있으며, ....
* ... 기능에 대한 콘트롤은 ... 메소드를 사용하여 수행한다.
* 이 클래스는 직렬화에 대해 보장되지 않았으므로 멀티쓰레드를
* 사용할 경우, ...한 방법을 적용해야 한다.
*
* @version 1.02 03/14/01
* @author 이동훈
* @see com.javacan.event.SomeEvent
* @since JDK1.3
*/
* 이 클래스는 ...을 위한 클래스다.
* 이 클래스는 ...한 경우 .... 역할을 수행한다.
* 이 클래스는 ...한 방법으로 사용될 수 있으며, ....
* ... 기능에 대한 콘트롤은 ... 메소드를 사용하여 수행한다.
* 이 클래스는 직렬화에 대해 보장되지 않았으므로 멀티쓰레드를
* 사용할 경우, ...한 방법을 적용해야 한다.
*
* @version 1.02 03/14/01
* @author 이동훈
* @see com.javacan.event.SomeEvent
* @since JDK1.3
*/
멤버 필드들의 선언
어떤 클래스는 많은 수의 필드 멤버를 가진다. 이런 경우 체계적으로 정리되지 않으면 관리하기 어렵다. 다음과 같은 형태로 정리한다.
- public 상수들 (즉, final 또는 static final 멤버 필드)
- public 변수들
- proteted 상수들
- proteted 변수들
- package 상수들
- package 변수들
- private 상수들
- private 변수들
- 한줄에 하나의 멤버 필드만 선언한다.
- public 및 protected 멤버 필드만은 Javadoc 주석을 첨부하는 것이 좋다.
- 상수(즉, final 멤버 필드)는 대문자만을 사용한다.
상수를 대문자로 표시하면 선언때뿐만이 아니라 수식같은 곳에서 사용될 때 상수임을 쉽게 알 수 있다. 다음은 java.lang.Math 클래스의 PI 상수 선언을 보여준다.
/**
* 원주율인 파이값에 대한 가장 근사치를 나타내는 double형의 값.
*/
public static final double PI = 3.14159265358979323846;
* 원주율인 파이값에 대한 가장 근사치를 나타내는 double형의 값.
*/
public static final double PI = 3.14159265358979323846;
생성자들
생성자 메소드는 다른 메소드들과 달리 객체 생성과 관련이 있으므로 멤버 필드 선언 뒤에 메소드 중 제일 먼저 위치하는 것이 좋다. 다른 규칙은 메소드 선언과 같이 적용된다.
메소드들 선언
메소드에 대한 선언에는 다음과 같은 규칙을 적용하는 것이 좋다.
- Javadoc 주석을 메소드 위에 첨부한다. (public 및 protected 메소드는 반드시)
- 메소드 수식어는 접근 제어 수식어(즉 public/protected/package/private)를 맨 처음 붙인다.
- 줄이 너무 길면 보기 좋게 여러 줄로 분리한다.
- 메소드 이름과 바로 다음 괄호인 ( 사이에 빈칸을 두지 않는다.
- 메소드의 파라미터를 닫는 괄호인 ) 와 메소드 코드 블록의 시작을 나타내는 { 사이에는 한칸 띈다.
- 파라미터들이 여러개일 경우 명료하게 파라미터들을 한줄에 한개씩 세로로 나란히 쓰는 것도 좋다.
/**
* 라디안 단위의 각도를 해당하는 도(degree)단위로 변환한다.
*
* @param angrad 라디안 단위의 각도
* @return angrad에 해당하는 각도의 도(degree)
* @since JDK 1.2
*/
public static double toDegrees(double angrad) {
return angrad * 180.0 / PI;
}
* 라디안 단위의 각도를 해당하는 도(degree)단위로 변환한다.
*
* @param angrad 라디안 단위의 각도
* @return angrad에 해당하는 각도의 도(degree)
* @since JDK 1.2
*/
public static double toDegrees(double angrad) {
return angrad * 180.0 / PI;
}
결론
소프트웨어 개발자들은 아마도 자신만의 코딩 스타일이 있을 것이다. 또한 언어의 발전에 따라 여러가지 코딩 스타일이 사용되어 왔다. 자신이 어떤 코딩 스타일이 좋다고 믿는 것은 큰 문제가 되지 않지만 가장 중요한 것은 역시 다른 사람에게 쉽게 이해될 수 있고 유지/보수될 수 있는 코딩 스타일이 가장 좋은 스타일이라는 점이다. 마치 가전제품에서 개발자만 좋다고 믿는 스타일보다는 소비자가 익숙한 스타일이 더 좋은 모델이듯이, 명료하고 읽기 쉬운 코딩 스타일이 좋은 코딩 스타일이라고 할 수 있다.
내 경험에 따르면 소프트웨어 개발이 끝난 뒤에 디버깅 과정과 유지/보수 과정에서 엔드 유저와 함께 코드를 검토하는 일이 빈번하다. 명료하지 못한 코드는 신뢰감을 떨어뜨리고 디버깅 및 트레이싱에도 많은 시간을 요구하게 하며, 유지/보수를 어렵게 만든다. 따라서 좋은 코딩 스타일을 평소에 몸에 익혀두는 것도 좋은 일이다.
본 글의 저작권은 이동훈에 있으며 저작권자의 허락없이 온라인/오프라인으로 본 글을 유보/복사하는 것을 금합니다.