1HOON
논리적 코딩
1HOON
전체 방문자
오늘
어제
  • HOME (187)
    • ☕️ JAVA (28)
      • WhiteShip Java LIVE Study (6)
      • Effective JAVA (10)
    • 🔮 KOTLIN (4)
    • 🌱 SPRING (51)
      • 스프링 인 액션 (22)
      • JPA (18)
    • ☕️ JAVASCRIPT (6)
    • 📃 DATABASE (40)
      • ORACLE (37)
      • MSSQL (2)
    • 🐧 LINUX (4)
    • 🐳 DOCKER (5)
    • 🐙 KUBERNETES (4)
    • 🏗️ ARCHITECTURE (8)
    • 📦 ETC (27)
      • TOY PROJECT (5)
      • RECRUIT (1)
      • 그냥 쓰고 싶어서요 (14)
      • TIL (1)
    • 🤿 DEEP DIVE (1)
    • 🚽 Deprecated (9)
      • PYTHON (3)
      • AWS (2)
      • HTTP 완벽가이드 (3)
      • WEB (1)

블로그 메뉴

  • 홈
  • 방명록
  • 관리

인기 글

최근 글

티스토리

hELLO · Designed By 정상우.
1HOON

논리적 코딩

☕️ JAVA

Enum을 사용해보자

2020. 10. 18. 16:47

요즘 1일 1커밋을 목표로 사이드 프로젝트를 진행중입니다.

 

애견샵을 관리하는 사이트를 만드는 프로젝트인데, 개 품종, 결재 수단 같은 거의 반 고정적이면서 비즈니스 로직에서 활용하는 데이터가 존재해 어떻게 처리를 할 지 고민하다 Enum을 사용해 처리를 했죠.

 

그 과정을 아래에 정리해봤습니다.

 

 

왜 Enum 을 사용했냐면...


맨 처음 생각한 방법은 데이터별 코드 테이블을 만들어 사용하는 방법이었습니다. 현재 회사에서 같은 방식으로 구성중이라 가장 먼저 생각난 방법입니다. 그러나 같은 이유로, 단점 또한 바로바로 생각이 났죠.

 

  • 데이터를 활용하기 위해서는 반드시 DB를 조회해와야 합니다.
  • 실제 비즈니스 로직의 코드 상에는 코드 값이 사용되고있어, 이 값이 의미하는 것을 바로 이해하기 어려웠습니다.
  • 만약 코드가 의미하는 데이터가 변경되면(그럴 일은 없을거라고 배웠지만, 실제로 일어나버렸습니다.), 해당 코드를 사용하는 모든 소스를 수정해야했습니다.
  • 코드 추가 시, 기존 레거시 코드나 다른 위치에서 어떤 코드를 사용하고 있는지 일일이 찾아 새로운 코드를 정의해야했습니다.
  • 서로 다른것을 의미하는 코드가 중복되는 사태가 있었습니다.
  • 코드 테이블을 사용하지 않는 경우 클래스마다 전역변수로 값을 선언해 사용했습니다.

 

이러한 이유로 작년에 Enum 을 활용해 코드를 정리하는 것을 건의했던게 생각나 Enum을 활용하기로 결정했습니다.(안타깝게도 이 건의는 기각됬습니다. ㅜㅜ)

 

당시 Enum을 활용하자고 건의한 이유는 아래와 같았습니다.

 

  • 코드가 단순해지고 가독성이 매우 좋아집니다.
  • 컴파일 시점에서 상수값의 안정성이 보장됩니다.
  • 아무래도 Enum이다보니, 코드상에서 값의 의도?가 바로 확인됩니다.(아, 이거 코드구나! 하고)

 

 

 

기초적인 방법


우선, 정말정말 기초적인 Enum 클래스를 작성해봤습니다.

 

1
2
3
4
public enum CustomerType
{
    MALTESE, YORKSHIRE_TERRIER, SHIH_TZU, POODLE
}
Colored by Color Scripter
cs

 

이 Enum 클래스는 개 품종을 열거하는 클래스인데, 확실히 코드상에서 가독성은 매우 좋아졌습니다. 코드의 의도도 확실히 보이고, 값의 안정성도 보장이 되었습니다.

 

그런데, 제가 필요한건 또 있었습니다. 이 품종의 한국 표기를 화면에 던져주고 싶었습니다.

위 코드 같은 경우에는 상수값만 존재하기 때문에 알 수가 없습니다.

 

 

 

한 발짝 더


클래스의 변수를 추가해보았습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public enum CustomerType
{
    MALTESE("말티즈")
    , YORKSHIRE_TERRIER("요크셔 테리어")
    , SHIH_TZU("시츄")
    , POODLE("푸들");
 
 
    private String korName;
 
    CustomerType (String korName)
    {
        this.korName = korName;
    }
 
    public String getKorName ()
    {
        return this.korName;
    }
}
cs

 

이제 getKorName 메서드를 호출하면, 지정한 한국 표기 내용이 반환됩니다. 예제 코드에는 Getter 메서드를 직접 작성했지만, 실제 코드에서는 Lombok @Getter 어노테이션을 사용했습니다.

 

이렇게 만들고나니, 또 욕심이 생겼습니다. 이 품종을 검색하는 기능을 만들 수 있을까?

 

 

 

기능 추가


한국 표기로 품종을 Like 검색하는 메서드를 추가해봤습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public enum CustomerType
{
    MALTESE("말티즈")
    , YORKSHIRE_TERRIER("요크셔 테리어")
    , SHIH_TZU("시츄")
    , POODLE("푸들");
 
 
    private String korName;
 
    CustomerType (String korName)
    {
        this.korName = korName;
    }
 
    public String getKorName ()
    {
        return this.korName;
    }
 
    public static List<CustomerType> findEnumByKorNameLike(String korName)
    {
        List<CustomerType> result = new ArrayList<>();
        for(CustomerType type : CustomerType.values())
        {
            if(type.getKorName().trim().indexOf(korName) > -1)
            {
                result.add(type);
            }
        }
        return result;
    }
}
Colored by Color Scripter
cs

 

이제 이 클래스를 사용하는 클래스에서는 아래와 같이 품종을 검색할 수 있습니다.

 

1
List<CustomerType> result = CustomerType.findEnumByKorNameLike("말티즈");
cs

 

 

 

리팩토링


위에서 추가한 메서드를 좀 더 세련되게 리팩토링 해보았습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public enum CustomerType
{
    MALTESE("말티즈")
    , YORKSHIRE_TERRIER("요크셔 테리어")
    , SHIH_TZU("시츄")
    , POODLE("푸들");
 
 
    private String korName;
 
    CustomerType (String korName)
    {
        this.korName = korName;
    }
 
    public String getKorName ()
    {
        return this.korName;
    }
 
    public static List<CustomerType> findEnumByKorNameLike(String korName)
    {
        return Arrays.stream(CustomerType.values())                
                    .filter(type -> type.getKorName().trim().indexOf(korName) > -1)
                    .collect(Collectors.toList());    
    }
}
 
Colored by Color Scripter
cs

 

 

 

더 알아보기


구현하고 싶은 내용은 모두 구현했으니, 마지막으로 Enum 클래스에 대해 좀 더 알아보겠습니다.

 

  1. 관련있는 값을 지정, 표현할 수 있습니다.
    • 예를 들어, 어떤 데이터의 사용 여부를 A에서는 1/0으로, B에서는 true/false로 관리하고 있다면 아래와 같은 방법으로 처리가 가능합니다.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      public enum TestEnum
      {
          USE(1, true)
          , NOT_USE(0, false);
       
          private int aValue;
          private boolean bValue;
          
          TestEnum(int a, boolean b)
          {
              this.aValue = a;
              this.bValue = b;
          }
       
          public int getAValue()
          {
              return this.aValue;
          }
       
          public boolean getBValue()
          {
              return this.bValue();
          }
      }
       
      cs
  2. 코드에 의미를 부여해줍니다.
    • A라는 상황에서 "1"이라는 값과 B라는 상황에서 "1"이라는 값이 가지는 의미는 분명히 다릅니다.
    • 단순히 문자열로 코딩을 하게 되면, 이 의미를 코드를 보고 알 수 없습니다.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      // 문자열만 사용했을 때
      String value = "1";
       
      if (value.equals("1"))
      {
          ...
      }
      else if (value.equals("2"))
      {
          ...
      }
      else
      {
          ...
      }
      cs
    • 하지만, Enum 을 사용하게 되면 값의 의미를 코드만 보고도 알 수 있습니다.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      // Enum을 사용했을 때
      String value = "1";
       
      if (value.equals(PaymentType.CASH))
      {
          ...
      }
      else if (value.equals(PaymentType.CARD))
      {
          ...
      }
      else
      {
          ...
      }
      Colored by Color Scripter
      cs
  3. DB 의존도를 낮출 수 있습니다.

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'☕️ JAVA' 카테고리의 다른 글

Try with Resources - 손쉬운 자원 해제  (0) 2021.03.09
BufferedReader 가 Scanner 보다 빠른 이유  (0) 2020.11.08
WebSocketSession에서 HttpSession를 얻는 방법  (1) 2020.09.10
Spring AOP와 AspectJ 비교하기  (14) 2019.12.15
이미지를 BLOB 형태로 DB에 저장하기  (5) 2018.09.09
    '☕️ JAVA' 카테고리의 다른 글
    • Try with Resources - 손쉬운 자원 해제
    • BufferedReader 가 Scanner 보다 빠른 이유
    • WebSocketSession에서 HttpSession를 얻는 방법
    • Spring AOP와 AspectJ 비교하기
    1HOON
    1HOON

    티스토리툴바