본문 바로가기
우아한테크코스/1주차 프리코스

[1주차 프리코스] 인터페이스 상수 → Enum으로!

by 행복한라이언 2023. 10. 24.
728x90
반응형

1. 참고

 

☕ 자바 Enum 열거형 타입 문법 & 응용 💯 정리

Enum 열거 타입 먼저 Enum은 "Enumeration"의 약자다. Enumeration은 "열거, 목록, 일람표" 라는 뜻을 가지고 있으며, 보통 한글로는 열거형이라고 부른다. 즉, 열거형(enum)은 요소, 멤버라 불리는 명명된 값

inpa.tistory.com

 

[JAVA] Enum 클래스에 대한 이해

0. 문제 제기 자바 1.5 버전 이전에는 상수를 선언할 때는 해당 클래스 내부에 final static Strirng, final static int와 같은 방식을 사용했습니다. 하지만 이런 방식의 상수 정의는 상수의 개수가 많아질

studyandwrite.tistory.com


2. 인터페이스 상수 사용한 이유

  • validLength 설정: validLength는 숫쟈 야구 게임의 규모를 결정하는 수이다. 현재는 3으로 되어 있지만 4자리, 5자리...n자리 숫자 야구 게임을 할 수도 있어 확장성을 위해서 쉽게 관리하기 위해서 사용했다.
    // 숫자 야구의 규모 결정
    int validLength = 3;

 

  • 문자열 관리 용이성: 성공한 코드에서 리팩토링 과정 중에 테스트 "FAILED" 발생했다. "~게임종료"를 빼먹고 옮기지 않았기 때문이다. 그래서 이건 문자열을 한 곳에서 관리할 필요를 느꼈다.
    // FAILED 
    "3스트라이크\n3개의 숫자를 모두 맞히셨습니다!"

    // 출력해야할 것
    "3스트라이크\n3개의 숫자를 모두 맞히셨습니다! 게임 종료"

 

  • 매직넘버 제거: 3스트라이크 이후에 게임을 멈출지, 다시할지 결정하는 방법은 "1" 또는 "2"를 입력하는 것이다. 그런데 1과 2가 그런 의미를 갖는 것을 직관적으로 알 수 없다. 이런 수를 매직넘버라고한다. 코드의 가독성을 위해서 상수로 관리할 필요를 느꼈다.
    • 1 → gameConitnue, 2 → GameStop
    String gameStop = "2";
    String gameContinue = "1";

3.  Enum으로 변경해보자!

  • 인터페이스 상수 → HintMessage Enum, SystemMessage Enum으로 분리
package baseball;

public interface Constants {
    // 숫자 야구의 규모 결정
    int validLength = 3;
    
    String hintAllStrikeMessage = "3스트라이크\n3개의 숫자를 모두 맞히셨습니다! 게임 종료";
    String hintNothingMessage = "낫싱";
    String hintStrikeMessageFormat = "%d스트라이크";
    String hintBallMessageFormat = "%d볼";
    String hintBallStrikeMessageFormat = "%d볼 %d스트라이크";
    String inputRequestMessage = "숫자를 입력해주세요 : ";

    String startGameMessage = "숫자 야구 게임을 시작합니다.";
    String continueGameMessage = "게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요.";
    String endGameMessage = "게임이 종료되었습니다.";

    String gameStop = "2";
    String gameContinue = "1";
}

 

  • HintMessage Enum: 숫자 야구 힌트에 관련된 상수 관리
package baseball;

public enum HintMessage {
    ALLSTRIKE("3스트라이크\n3개의 숫자를 모두 맞히셨습니다! 게임 종료"),
    NOTHINGMESSAGE("낫싱"),
    STRIKEFORMAT("%d스트라이크"),
    BALLFORMAT("%d볼"),
    BALLSTRIKFORMAT("%d볼 %d스트라이크");

    
    private final String message;

    HintMessage(String message) {
        this.message = message;
    }
    public String get() {
        return message;
    }
}

 

  • SystemMessage Enum: 게임에 진행과 관련된 상수 관리
package baseball;

public enum SystemMessage {
    INPUTREQUEST("숫자를 입력해주세요 : "),

    STARTGAME("숫자 야구 게임을 시작합니다."),
    CONTINUEGAME("게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요."),
    ENDGAMEM("게임이 종료되었습니다."),

    GAMESTOP("2"),
    GAMECONTINUE("1");
    final private String message;

    SystemMessage(String message){
        this.message = message;
    }
    public String get(){
        return message;
    }
}

 

  • validLength는 상수 인터페이스에 유지
package baseball;

public interface Constants {
    // 숫자 야구의 규모 결정
    int validLength = 3;
}

소감

 '2. 인터페이스 상수를 사용한 이유'때문에 '인터페이스 상수'를 사용했었는데 리팩토링 과정 중 '인터페이스 상수'가 부적절할 수 있다는 글을 보게 되었다. 그래서 구글링을 통해 '인터페이스 상수' 대신 Enum를 쓰는 이유에 대해서 알게 되었다. 다만 내가 지금 하는 미션에 적절한가에 대해서는 의문이 들었는데, '1.참고'에서 발생하는 에러가 날 수 있는 상황이 아니기 때문에 굳이 해야할까라는 생각을 했다.

 

☆ 서로 다른 인터페이스에서 정의된 CAMPUS.Jamsil과 TRACK.BE 비교가 되고 있다.

package sec08;

interface CAMPUS{
    int JamSil = 1;
    int Seolleung = 2;
}

interface TRACK{
    int BE = 1;
    int FE = 2;
    int AN = 3;
}

public class EnumPractice {
    public static void main(String[] args) {

        if(CAMPUS.JamSil == TRACK.BE){
            System.out.println("두 상수는 같습니다"); // 두 상수는 같습니다.
        }

        int track = TRACK.BE;

        switch (track){
            case TRACK.BE:
                System.out.println("백엔드"); // 백엔드
                break;
            case TRACK.FE:
                System.out.println("프론트엔드");
                break;
            case TRACK.AN:
                System.out.println("안드로이드");
                break;
        }
    }
}

 

 그래도 기존에는 '인터페이스 상수'에서 모든 상수를 관리해 상수의 수가 많아질수록 공백으로 나누어 놓긴 했지만, 어떤 의도의 상수인지 파악하기 위해서는 사용 되는 코드를 직접 봐야 했다. 그런데 HintMessage, SystemMessage를 분리시켜서 Enum으로 각각 관리하니 관리해야할 상수의 수도 줄어들고 이 상수가 의미하는 바를 쉽게 파악할 수 있었다. 하지만 2가지 정도의 불편사항도 발생했다.


1) 불편사항1. Enum명.~~~.get()으로 맵핑된 값을 얻다보니까 너무 가로로 길어지는 현상이 발생했다.

HintMessage.BALLSTRIKFORMAT.get().formatted(cntB, cntS);

 

2)불편사항2. 상수 인터페이스를 사용했을 때는 import static을 통해서 해당 상수를 직접 가져와 오히려 코드가 가독성이 좋았는데 Enum을 사용하니 불편사항1에서 언급한 것처럼 너무 길어지고 오히려 가독성이 떨어지는 느낌도 받았다.

 

728x90
반응형