분류 전체보기
훗~
DSLR
Mac
Reference
private
Enum에 해당되는 글
2008.11.05

[Java] State를 more stylish하게 유지 하려면?

State를 more stylish하게 유지 하려면..
이라.. 제목은 거창한데 사실 별거 아니고,
역시나 초보적인 고민인데.. (-- )( --);;

일단 아래 코드를 보면..
각 situation에 따라서 State class의 'State'를 바꾸어 주는건데..
참 단순무식하게 코딩해놨다..;;


머, 사실 이렇게 하는게 틀렸다거나 하는건 아니지만..
이런 코드가 여기저기 난립하게 된다면,
유지보수에 있어 큰 문제가 생길것이다..
(사실 지금 생겼었다..)

"몇몇 필요로 하는 'State'에 대해서 한군데 모아놓고 처리할 좋은 방법이 없을까?"

결국 이 고민에 대한 답을 찾고자 하는것인데..

단무지틱한 생각으로 접근하면..
정말 단순하게 해결(?)된다..


한군데서 모아서 처리해야 한다는 전제를 충족시켜 주기에..
머 나쁘지 않다..하지만 Stylish하지는 않다..

그렇다면
Enum type을 써서 만들어 보면 어떨까..??


움..해놓고 보니..
썩 좋아보이지는 않는다.. ;;
more Stylish 보다는 more '귀찬아'질듯..ㅎㅏ하하하하


일단 고민 좀 더 해봐야 할듯..ㅋ;




락군

[Java] Enum..

Enum..
이렇게 사용할 수도 있구나..






락군

Java5의 Enum 사용하기

Java5에서 Enum은 기존의

public interface XYZConstants {
  public static final int A = 1;
  public static final int B = 2;
  public static final int C = 3;
}

가 갖는 문제점을 해결합니다. 위와같은 integer를 사용한 constants는 결국
int c = XYZConstatnts.B;
와 같은 형태로 값을 저장해야하고 따라서 아무 값이나 c안에 저장할 수 있다는 문제가 있습니다. 이를 해결학위한 Typesafe Enumeration 패턴이 있지만 이는 구현하기 어렵고, switch-case문을 사용하지 못하는 한계가 있죠. 이를 해결한 것이 Java5의 Enum입니다.

Enum은 보통 다음과 같이 선언합니다.

public enum SimpleEnum {
  A, B, C;

  public static void main(String[] args) {
    System.out.println(A);

    SimpleEnum s = B;
    switch(B) {
      case A: System.out.println(“A”); break;
      case B: System.out.println(“B”); break;
      case C: System.out.println(“C”);
    }
  }
}

출력은 다음과 같습니다.
A
B

인자를 저장시켜 활용할 수도 있습니다.

public enum EnumWithArgument {
  A(0,1), B(1, 2), C(2, 3);

  private int first;
  private int second;

  // No modifier is allowed here.
  EnumWithArgument(int a, int b) {
    first = a;
    second = b;
  }

  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append(first);
    sb.append(“, “);
    sb.append(second);

    return sb.toString();
  }

  public static void main(String[] args) {
    System.out.println(A);
  }
}

출력은 다음과 같습니다.
0, 1

흥미로운 것은 Enum의 hierarchy입니다.
만약 단순히 Enum을 선언하면 hierarchy는 다음과 같이 됩니다.

public enum EnumSuper {
  A;

  public static void main(String[] args) {
    System.out.println(A.getClass());
    System.out.println(A.getClass().getSuperclass());
  }
}

출력은 다음과 같습니다.
class EnumSuper
class java.lang.Enum

하지만 다음과 같이 Enum을 추상클래스로 만들고 각각의 item이 override하게 할 수도 있습니다.

public enum EnumSuper2 {
  A() { @Override public void foo() { } };

  abstract void foo();

  public static void main(String[] args) {
    System.out.println(A.getClass());
    System.out.println(A.getClass().getSuperclass());
  }
}

출력은 다음과 같습니다.
class EnumSuper2$1
class EnumSuper2

따라서 각 Enum 안의 value에 polymorphism 적용이 가능하게 됩니다.

public enum EnumSuper3 {
  A { @Override public void foo() { System.out.println(“I am A”); } },
  B { @Override public void foo() { System.out.println(“I am B”); } };

  abstract public void foo();

  public static void main(String[] args) {
    EnumSuper3 e = A;
    e.foo();

    e = B;
    e.foo();
  }
}

출력은 다음과 같습니다.
I am A
I am B

switch-case를 써서 다음과 같이 한 곳에서 처리하게 할 수도 있습니다.

public enum EnumSuper3 {
  A, B;

  public void foo() {
    switch(this) {
      case A: System.out.println(“I am A”); break;
      case B: System.out.println(“I am B”); break;
    }
  }

  public static void main(String[] args) {
    EnumSuper3 e = A;
    e.foo();

    e = B;
    e.foo();
  }
}

출력은 마찬가지입니다.
I am A
I am B

이렇게까지 보고 “기능은 참 많구나…” 하고 끝내면 좋은데 문제는 Enum의 정의된 모양이 무척 이해하기 어렵다는 것입니다.

JDK API에 Enum은 다음과 같이 정의되어 있습니다.

Class Enum<E extends Enum<E>> implements Serializable, Comparable<E> { … }

먼저 Enum은 상수이므로 Serializable 해야한다는 것은 명확합니다.
또 Enum의 각 value간 비교가 가능해야할 것이므로 Comparable<E> 을 구현한 것도 이해할 수 있습니다.
문제는 Enum<E extends Enum<E>>입니다.

앞서 이야기 드렸던 바와 같이 enum으로 선언한 클래스는 Enum을 상속받습니다.
그리고 이 동작은 내부적으로 자동으로 이루어집니다.
따라서 public enum Foo는 Enum<Foo extends Enum> 을 만족합니다. 문제는 Foo extends Enum<Foo> 부분에서 부모 클래스에 넘기는 Foo 입니다. 이것은 generics에서 상속을 강제할 경우 어떤일이 생기는가를 따져보면 이해할 수 있습니다.

1) 여기에서 보다시피 자식 클래스는 부모의 클래스를 물려받으며, 의무적으로 부모의 abstract 메소드를 구현해야 합니다.
2) 또한 covarint 를 가능하게 합니다. 예를들어 Enum 클래스안에 public <E> E method() 가 있었다면 이 E 는 자동으로 enum 으로 선언된 클래스 (지금의 예에서는 Foo)로 치환됩니다.

이처럼 java generics 의 특징은 C++에서 코드가 직접 생성되는 경우와 매우 다른 특징을 가지며 Enum은 그것을 잘 활용한 예입니다.

락군
*1