주요글: 도커 시작하기
반응형
잘 구성된 자바 코드의 전체적인 체계에 대해서 알아본다.

소스 파일

자바 소스 코드를 체계적으로 이해할 수 있도록 작성하려면 클래스의 선언과 클래스 멤버들에 대한 체계적인 배치가 필요하다. 소스 파일에 코드 구성의 체계에는 여러 방법이 있을 수 있지만 잘 구성된 소스 파일은 보통 다음과 같은 순서를 가진다. 각 항목들 사이에는 반드시 빈 줄을 삽입하여 보기 좋게 만든다.

  • 파일 머릿말 주석 (필요할 경우)
  • 패키지 선언
  • Import 문장들
  • 클래스 선언/구현
    • Javadoc 주석
    • 클래스 선언
    • 멤버 필드들의 선언
    • 생성자들
    • 메소드들 선언(main() 메소드 제외)
    • inner 클래스들 (있을 경우)
    • main() 메소드 (있을 경우)
파일 머릿말 주석

파일 머릿말 주석은 파일에 포함된 클래스 이름/버전/날짜 등과 저작권 등을 표시한다. 파일 맨 처음에 위치하므로 인덱스로서도 사용할 수 있다. 필요없으면 생략해도 된다.

import 문장들

복잡한 클래스는 여러개의 import 문장을 가지는 경우가 많다. 이런 import 문장들은 java.awt.* 처럼 패키지 전체를 import 하는 경우도 있고, java.awt.Button 처럼 개별 클래스들을 import 하는 경우도 있다. import 문장들을 체계적으로 다루려면 다음과 같은 순서로 한다.

  • 자바 표준 클래스들 (java.io.* 등 java. 으로 시작하는 패키지의 클래스들)
  • 자바 확장 클래스들 (javax. 으로 시작하는 패키지의 클래스들)
  • 서드-파티 제품 클래스들 (즉, 구매한 패키지 제품들의 클래스들)
  • 애플리케이션 클래스들 (즉, 해당 애플리케이션을 위해 만든 클래스들)
서드-파티 클래스들이나 애플리케이션 클래스들에는 어떤 목적을 위한 클래스 또는 패키지인지 주석을 첨부하는 것이 좋다. 간단히 각 라인 뒤에 // 방식의 주석을 사용해도 좋지만 import 문장 윗부분에 모아서 설명하는 것이 좋다.

// 자바 클래스들
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
 */

멤버 필드들의 선언

어떤 클래스는 많은 수의 필드 멤버를 가진다. 이런 경우 체계적으로 정리되지 않으면 관리하기 어렵다. 다음과 같은 형태로 정리한다.

  • public 상수들 (즉, final 또는 static final 멤버 필드)
  • public 변수들
  • proteted 상수들
  • proteted 변수들
  • package 상수들
  • package 변수들
  • private 상수들
  • private 변수들
또한, 다음과 같은 규칙을 같이 적용하는 것이 좋다.

  • 한줄에 하나의 멤버 필드만 선언한다.
  • public 및 protected 멤버 필드만은 Javadoc 주석을 첨부하는 것이 좋다.
  • 상수(즉, final 멤버 필드)는 대문자만을 사용한다.
package 및 private 필드 멤버들은 같은 클래스/패키지 내에서만 사용되므로 간단한 주석으로 충분하지만, public 및 protected 멤버 필드는 다른 패키지의 클래스에서 사용되므로 Javadoc 주석이 있으면 패키지에 대한 API 규약을 손쉽게 만들 수 있다.

상수를 대문자로 표시하면 선언때뿐만이 아니라 수식같은 곳에서 사용될 때 상수임을 쉽게 알 수 있다. 다음은 java.lang.Math 클래스의 PI 상수 선언을 보여준다.

    /**
     * 원주율인 파이값에 대한 가장 근사치를 나타내는 double형의 값.
     */
    public static final double PI = 3.14159265358979323846;

생성자들

생성자 메소드는 다른 메소드들과 달리 객체 생성과 관련이 있으므로 멤버 필드 선언 뒤에 메소드 중 제일 먼저 위치하는 것이 좋다. 다른 규칙은 메소드 선언과 같이 적용된다.

메소드들 선언

메소드에 대한 선언에는 다음과 같은 규칙을 적용하는 것이 좋다.

  • Javadoc 주석을 메소드 위에 첨부한다. (public 및 protected 메소드는 반드시)
  • 메소드 수식어는 접근 제어 수식어(즉 public/protected/package/private)를 맨 처음 붙인다.
  • 줄이 너무 길면 보기 좋게 여러 줄로 분리한다.
  • 메소드 이름과 바로 다음 괄호인 ( 사이에 빈칸을 두지 않는다.
  • 메소드의 파라미터를 닫는 괄호인 ) 와 메소드 코드 블록의 시작을 나타내는 { 사이에는 한칸 띈다.
  • 파라미터들이 여러개일 경우 명료하게 파라미터들을 한줄에 한개씩 세로로 나란히 쓰는 것도 좋다.
다음은 java.lang.Math 클래스의 toDegrees 메소드를 보여주는 예다.

    /**
     * 라디안 단위의 각도를 해당하는 도(degree)단위로 변환한다.
     *
     * @param   angrad   라디안 단위의 각도
     * @return  angrad에 해당하는 각도의 도(degree)
     * @since   JDK 1.2
     */
    public static double toDegrees(double angrad) {
        return angrad * 180.0 / PI;
    }

결론

소프트웨어 개발자들은 아마도 자신만의 코딩 스타일이 있을 것이다. 또한 언어의 발전에 따라 여러가지 코딩 스타일이 사용되어 왔다. 자신이 어떤 코딩 스타일이 좋다고 믿는 것은 큰 문제가 되지 않지만 가장 중요한 것은 역시 다른 사람에게 쉽게 이해될 수 있고 유지/보수될 수 있는 코딩 스타일이 가장 좋은 스타일이라는 점이다. 마치 가전제품에서 개발자만 좋다고 믿는 스타일보다는 소비자가 익숙한 스타일이 더 좋은 모델이듯이, 명료하고 읽기 쉬운 코딩 스타일이 좋은 코딩 스타일이라고 할 수 있다.

내 경험에 따르면 소프트웨어 개발이 끝난 뒤에 디버깅 과정과 유지/보수 과정에서 엔드 유저와 함께 코드를 검토하는 일이 빈번하다. 명료하지 못한 코드는 신뢰감을 떨어뜨리고 디버깅 및 트레이싱에도 많은 시간을 요구하게 하며, 유지/보수를 어렵게 만든다. 따라서 좋은 코딩 스타일을 평소에 몸에 익혀두는 것도 좋은 일이다.



본 글의 저작권은 이동훈에 있으며 저작권자의 허락없이 온라인/오프라인으로 본 글을 유보/복사하는 것을 금합니다.

+ Recent posts