본문 바로가기
JAVA

enum으로 코드 줄이기

by enai 2019. 9. 4.

enum은 열거형(enumerated type)이라고 부른다.

열거형은 서로 연관된 상수들의 집합이라고 한다.

 

만약, price라는 객체의 getType() 메서드가 각 가격의 좌석 종류를 가져오고, 각 좌석 종류가 무슨 좌석인지를 표현해야 한다고 했을 때,

if문으로 다음과 같이 표현할 수 있다.

if(price.getType() == "A"){
  System.out.println("VIP석");
} else if(price.getType() == "B"){
  System.out.println("B구역");
} else if(price.getType() == "C"){
  System.out.println("C구역");
} else if(price.getType() == "S"){
  System.out.println("스탠딩석");
}

 

하지만 좌석 종류가 많아질수록 위 같은 코드는 비효율적이 된다.

 

이때, enum을 사용해서 간단하게 처리할 수 있다.

참고로 enum은 사실상 class이며, 편의를 위한 enum만의 문법적 형식이 있고, 구분을 위해 따로 enum이라는 키워드를 사용한다.

 

enum PriceType{
  A, B, C, S;
}

이렇게 enum으로 상수끼리 묶을 수 있다.

이 코드는 사실상 아래 코드와 같다.

class PriceType{
  public static final PriceType A = new PriceType();
  public static final PriceType B = new PriceType();
  public static final PriceType C = new PriceType();
  public static final PriceType S = new PriceType();

  private PriceType(){}
}

위 코드로 알 수 있는 것은 enum의 생성자의 접근 제어자가 private라는 것이다.

이는 클래스 PriceType을 인스턴스로 만들 수 없다는 것을 의미한다. 즉, 다른 용도로 사용하는 것을 금지한다는 것이다.

enum은 많은 곳에서 사용하던 디자인 패턴을 언어가 채택해서 문법적인 요소로 단순화시킨 것이라고 한다.

 

 

다음과 같이 enum으로 상수를 선언하면서 동시에 생성자를 호출할 수 있다.

enum PriceType{
  A("VIP석"), B("B구역"), C("C구역"), S("스탠딩석");
  
  private String name;
  
  PriceType(String typeName){
    this.name = typeName;
  }
}

 

위 코드 중, 아래 부분과 같은 코드가 생성자이다.

PriceType(String typeName){
  this.name = typeName;
}

상수를 선언하면서 생성자를 호출하며 괄호 안에 쓴 값이, 이 생성자의 매개변수 값으로 전달된다.

이 전달된 typeName 값은 this.name으로 enum 안에 선언된 변수에 저장된다.

 

enum은 사실상 class인 만큼, enum은 메서드를 가질 수도 있다.

enum PriceType{
  A("VIP석"), B("B구역"), C("C구역"), S("스탠딩석");
  
  private String name;
  
  PriceType(String typeName){
    this.name = typeName;
  }
  
  String getName(){
    return name;
  }
}

위처럼 getName() 메서드를 추가해주었다.

 

 

그럼 이제 좌석 종류가 A인 좌석의 이름을 출력하려면 다음과 같이 할 수 있다.

System.out.println(PriceType.A.getName());

 

하지만 price.getType()으로 호출한 값으로 좌석의 이름을 알아내려면 아직 위 코드로는 부족하다.

 

enum의 valueOf라는 메서드가 있다.

이 valueOf 메서드는 매개변수로 받은 값과 같은 이름을 가진 열거형 상수를 리턴한다.

PriceType.valueOf("A");

즉, 이렇게 하면 A라는 이름을 가진 PriceType의 상수를 리턴한다.

 

 

이 valueOf를 이용하면 price.getType()으로 호출한 값으로 PriceType의 메서드를 호출할 수 있다.

이제 각 타입에 맞는 좌석 이름을 출력하는 코드를 다시 만든다면 다음과 같다.

String priceTypeName = PriceType.valueOf(price.getType()).getName();
System.out.println(priceTypeName);

 

 

 

 

모든 코드를 합치면 다음과 같다.

enum PriceType{
  A("VIP석"), B("B구역"), C("C구역"), S("스탠딩석");
  
  private String name;
  
  PriceType(String typeName){
    this.name = typeName;
  }
  
  String getName(){
    return name;
  }
}


public class ConstantDemo {
  public static void main(String[] args) {
    String priceTypeName = PriceType.valueOf(price.getType()).getName();
    System.out.println(priceTypeName);
  }
}

 

main 함수 안의 기능이 처음에 price라는 객체의 getType() 메서드로 가져온 좌석 종류에 해당하는 좌석 이름을 출력하는 코드이다.

다시 if문으로 작성했던 코드와 비교해보면,

if(price.getType() == "A"){
  System.out.println("VIP석");
} else if(price.getType() == "B"){
  System.out.println("B구역");
} else if(price.getType() == "C"){
  System.out.println("C구역");
} else if(price.getType() == "S"){
  System.out.println("스탠딩석");
}

9줄에서 2줄로 굉장히 짧아졌다.

 

 

 

 

 

enum을 사용하는 이유는 아래와 같다.

  • 코드가 단순해진다.
  • 인스턴스 생성과 상속을 방지한다.
  • 키워드 enum을 사용하여, 구현의 의도가 열거임을 분명하게 나타낼 수 있다.

 

해당 게시물에서는 코드가 단순해지는 것과 구현 의도를 분명히 할 수 있다는 것만 알 수 있었지만,

이 게시물 내용의 출처인 생활코딩 페이지에는 더 많은 내용이 있다.

 

 

 

 

출처)

생활코딩 - 상수와 enum

Oracle Docs - Enum (Java Platform SE 7 )

댓글