기나긴 고민뒤에 Type safe enumeration pattern이라는 것을 발견하고 public static finale int 로 정의된 열거

형 변수들을 정리 하고 있습니다.

C언어에서는 enum구문이 자바에는 없습니다.

 (Enumeration이라는 인터페이스가 있지만 C/C++의 enum과 달리 iterator입니다.)

C에서는

#define TERMINAL 0

#define PROCESS 1

#define LINE 2

...

이런식으로 하던지, 

typedef enum { TERMINAL, PROCESS, LINE, ARROW, ...}symbolType;

이런식으로 사용했습니다.

하지만 자바에서는(물론 자바에서만은 아니겠지만 지금은 자바만 생각하고 있습니다.) 어떻게 해야 할지 몰랐습니다.

그래서 C와 비슷한 방식으로, 클래스안에 값을 직접 적어 넣었습니다.(일종의 하드 코딩을 했습니다.)

Class DSymbol{

public static final int TERMINAL = 0;
public static final int PROCESS = 1;
public static final int LINE = 2;
}


아직까지 이렇게 했을때 큰 문제점을 없었습니다. 있다고 한다하더라고 큰 문제는 없을 것입니다.

하지만!!! 아름다운 코드를 만들기위해서 이렇게 하면 안좋다는 것을 알게 되었습니다.


문제점을 찾아보니 

1. 새로운 상수를 추가 했을 경우 사용자 코드도 다시 컴파일 해야 한다.

2. 새로운 상수가 사용자 코드와 충돌을 일으킬 수 있다.

3. 이런 방식은 출력 가능한 문자열로 바꾸거나, 상수들을 모두 열거할 수 있는 방법을 제공하지 않는다.

그리고 이펙티브 자바책을 보니 "public static final String TERMINAL = "TERMINAL";"로 구현 해도 안된다고 합니다.

이경우 사용자가 TERMINAL과 같은지 비교 하기 위해 "TERMINAL"이라는 문자열을 코드에 직접 넣을 경우, 타이핑

오류를 런타임에 확인 할 수 없고, 디버깅이 어려지기 때문이죠. 

1.번과 2.번과 같은 경우는 내가 짠것을 나만 쓴다면 이런 문제가 없겠지만 이것을 API화 하여 다른 사람이 이것을 쓰

거나 팀프로젝트를 할 경우, 다른 팀원이 나의 클래스를 사용할 경우에 문제가 될 수 있습니다. 

(항상 내코드는 남이 쓸것이다라는 생각을 해야 좋은 코드가 나올 것 같네요..)


이런 문제점을 해결하기 위한 좋은 방법이 있습니다.

Type safe enumeration pattern이라는 것이 있습니다.

가장 간단한 구현은 다음과 같습니다.

public class DSymbolType {

    private final String type;

    private DSymbolType(String type){

        this.type = type;

    }

    public String toString(){

        return type;

    }
    public static final DSymbolType Terminal = new DSymbolType("Terminal");
    public static final DSymbolType Process = new DSymbolType("Process");
    public static final DSymbolType Decision = new DSymbolType("Decision");
}

이 방법의 좋은 점은 다음과 같습니다.


1. static final필드에서 정의된 객체 외에 다른 객체가 생성될 수 없다.

2. 컴파일 시점의 타입 안정정을 제공해준다.

3. 새로운 상수가 추가되더라도 client코드를 변경할 필요가 없다.

4. 상수를 출력가능한 문자열로 문자열로 바꿀수 있다.

1. 같은 경우는 클래스가 final선언이 되어 있지 않지만 생성자가 private으로 선언되어 있으므로, 

이 함수를 상속받더라고 생성자를 호출 할 수 없어서서 결국 상속 받을 수 없다. 따라서 정해진 객체만 참조 할 수 있

는 것이겠죠.

2. 번 은 이 타입안정 열거형을 사용했을 경우, DSymbol의 객체는 NULL아니면 세개 중의 하나겠죠,

 그러므로 잘못된 코드를 작성할 경우 컴파일 타임에 그것을 알게 될 것입니다.

3. 예전에는 새로운 상수가 추가 되면 client 쪽 코드도 변경이 되어야 했지만 이렇게 함으로서 client쪽 코드를 변경

하지 않아도 되게 되었습니다. OCP원칙을 지키게 되었네요.ㅋ

4. 클래스의 toString() 함수를 이용함으로써 상수를 문자열로 제공 할 수 잇는 수단이 생겼습니다.


기본적인 타입 안전 열거형을 업그레이드 하는 버전이 많지만 오늘을 여기 까지 해야 겠네요..


아무튼 저의 코드가 아름다워 지고 있습니다~~


와~~ 만세~~~

신고
by danguria 2009.10.20 23:58
| 1 |