1주차 프리코스 미션 <숫자 야구 게임>의 기능 목록 중 게임을 재시작할 것인지 종료할 것인지 입력 받는 기능을 구현해야 했습니다.
게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.
1
이때 입력받은 값을 검사하는 부분에서 1
이나 2
를 하드 코딩하는 것을 피하기 위해 final
변수로 선언해주었습니다.
그렇게 되면 종료/재시작을 검사하는 것에만 클래스 내 변수가 2개가 생성됩니다.
👉 final
로 하드 코딩을 피하지만 내부 변수가 너무 많아진다는 점이 걸렸습니다.
그래서 처음에는 게임 시작과 종료에 대한 데이터를 가지고 있는 Game
클래스를 만들어주었습니다.
class Game {
private static int START = 1;
private static int END = 2;
}
위와 같이 만드는 것은 클래스 내 선언하는 부분에서 네이밍이 겹칠 수 있고 불필요하게 상수가 많아지는 단점이 있다고 합니다.
인터페이스로 관리하는 경우 : 위의 문제가 줄어들지만 여전히 IDE의 지원을 적극적으로 받을 수 없고 타입 안정성이 떨어진다고 합니다.
Enum
이란?
열거형이라 불리며, 서로 연관된 상수들의 집합을 의미합니다.
Enum
의 장점
- 문자열과 비교해 IDE의 적극적인 지원을 받을 수 있습니다.
- 허용 가능한 값들을 제한할 수 있습니다.
- 리팩토링시 변경 범위가 최소화됩니다.
C/C++은Enum
이int
값이지만 Java의Enum
은 기능을 갖춘 클래스라고합니다.
클래스에 상수만으로 작성되어 있으면 반드시 class로 선언할 필요는 없고, enum
을 선언하여 이 객체가 '상수의 집합'이라는 것을 명시적으로 나타낼 수 있습니다.
public enum GameType {
START("1"), END("2");
private String gameButton;
GameType(String value) {
this.gameButton = value;
}
public boolean equals(String input){
return gameButton.equals(input);
}
}
GameType
클래스를 상수처럼 사용할 수 있습니다. : GameType.START
Enum
클래스를 구현하는 경우 상수 값과 유일하게 하나의 인스턴스가 생성되어 사용됩니다. 👉 Singletone
형태로 사용되기 때문에 thread
환경에 유의enum
으로 구현 👉 상수간의 관계를 파악할 수 있습니다.Enum
클래스가 가지고 있는 모든 상수 값을 배열의 형태로 리턴합니다.
즉, Enum
클래스가 가지고 있는 모든 인스턴스를 배열에 담아 반환합니다.
GameType[] types = GameType.values()
for (int i=0; i<types.length; i++) {
System.out.println(types[i]);
}
// START, END
String
을 파라미터로 받는데 인자로 들어온 String
과 일치하는 상수 인스턴수가 존재하면 그 인스턴스를 반환합니다.
System.out.println(GameType.valueOf("START"));
// START
Enum
클래스 내부 상수들의 인덱스를 리턴하는 메소드입니다.
주의할 점은 gameButton
값과 별개인 Enum
인덱스임에 주의해야합니다.
GameType[] types = GameType.values();
for (int i = 0; i < types.length; i++) {
System.out.println(types[i].ordinal());
}
// 0 1
name()
: 호출된 값의 이름을 String
으로 리턴한다.compareTo(E o)
: 이 Enum
과 지정된 객체의 순서를 비교한다. 지정된 객체보다 작은 경우 음의 정수, 동일하면 0, 크면 양의 정수를 반환한다.equals(Object other)
: 지정된 객체가 이 Enum
정수와 같은 경우 true를 반환한다.equals
의 경우 객체를 비교하는 것에 유의해야합니다.
System.out.println(GameType.START.equals(GameType.START));
System.out.println(GameType.START.equals("START"));
System.out.println(GameType.START.equals("1"));
// true
// false
// false
관련되어 있지만 관련성을 표시하기 힘든 형태의 데이터를 한 곳에서 관리할 수 있는 것에 Enum
이 적절하다고 합니다.
public enum payGroup {
CASH("현금", <현금 결제 수단 리스트>)
CARD("카드", <카드 결제 수단 리스트>)
ETC(...)
...
}
뿐만 아니라 상태(값)와 행위(메소드)를 한 곳에 관리하여 관련 로직을 쉽게 확인할 수 있습니다.
public enum CalculatorType {
A(value -> value),
B(value -> value * 10),
C(value -> value * 3),
D(value -> 0L);
private Function<Long, Long> expression;
CalculatorType(Fuction<Long, Long> expression) { this.expression = expression; }
public long calculator(long value) { return expression.apply(value); }
}
서로 다른 계산식(A
, B
, C
, D
)을 사용할 때 다음과 같이 표현하여 Enum
내부에서 타입에 알맞게 표현식을 찾아주는 방식입니다.
(Lambda
를 사용하여 중복될 수 있는 기능(calculator
)를 하나로 만들어줍니다.)
글을 다 정리하고 보니 뭔가 부족한 느낌이 드네요...
제가 직접 Enum
을 이것저것 활용해보고 추가적인 내용을 정리해보도록 하겠습니다! 💪
쉽게 설명하고 싶은데 생각보다 쉽지 않네여..😂