[개요]
프로젝트를 진행하다 class 내에서 사용할 상수 문자열들을 관리할 때가 온다. 이들을 다른 언어에선 enum으로 의미를 갖는 집합을 만들어 사용하곤 했는데 자바에서는 귀찮은 부분이 있는 것 같다. 이를 다뤄본 후기를 적어본다.
[본문]
1. private 필드 및 getter 사용하기
private enum Role {
ADMIN("ADMIN"), // enum 은 내부에서 private 생성자를 호출하여 문자열을 초기화 한다.
USER("USER");
private final String value;
private Role(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
특정 class 내에서만 사용하는 enum은 private enum으로 만들었다. 그런데 이를 사용하려니 아래처럼 복잡한 코드가 되어 버렸다.
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeHttpRequests(auth -> auth
.requestMatchers(WHITE_LIST).permitAll()
.requestMatchers(ADMIN_LIST).hasRole(Role.ADMIN.getValue())
.requestMatchers(LOGIN_LIST).hasAnyRole(Role.ADMIN.getValue(), Role.USER.getValue())
.anyRequest().authenticated()
);
return httpSecurity.build();
}
이렇게 사용할 바에야 차라리 상수값 그대로 사용하는 게 복잡도를 더 낮추는 것처럼도 보인다. 현재는 관련 있는 문자열들을 집합으로 묶긴 했는데 이후 변경 가능성도 없는 문자열 상수라 이렇게 까지 많은 비용을 들이면서 enum을 사용할 필요는 없어 보인다.
2. public 필드 사용하기
private enum Role {
ADMIN("ADMIN"), // enum 은 내부에서 private 생성자를 호출하여 문자열을 초기화 한다.
USER("USER");
public final String value;
private Role(String value) {
this.value = value;
}
}
이처럼 사용하면 바로 Role.ADMIN 같이 꺼낼 수 있을까 했는데 ADMIN, USER라는 값은 Role이라는 타입으로 문자열이 아니었다. 사용하려면 Role.ADMIN.value와 같은 방식으로 사용해야 한다. 이는 객체지향도 깨는 것 같은데 거기에 private 필드를 사용했던 첫 번째 방법과 크게 다르지 않아 이를 선택할 이유가 없다.
3. 초기화 없이 사용하기
private enum Role {
ADMIN,
USER;
}
위와 같이 사용하면 Role.ADMIN 이라 하면 Role 타입이고, Role.ADMIN.name()이라 하면 필드의 이름을 내뱉고, Role.ADMIN.ordinal()이라 하면 초기화 되어 있는 상수값인 0을 뱉는다. 역시 이도 너무 길어져서 (1) 거의 변하지 않는 값이고 (2) 짧은 길이의 데이터인데 비슷한 의미의 집합을 만들기 위해 enum까지 사용할 이유를 느끼진 못했다.
[결론]
앞으로는 class 내에서 문자열 상수를 사용하려면 private final String ADMIN = "ADMIN";과 같이 사용할 것 같다. 같은 의미의 집합으로 묶지는 못하겠지만, 두 번 이상 사용할 수 있는 문자열을 상수 그대로 사용하기에는 재사용성이 떨어질 것 같기 때문이다. 만약 한 번만 사용한다면 굳이 필드로 뺄 필요도 없긴 할 것 같다. 이렇게 사용하다 필요에 의해 리팩토링하는 방식으로 하는 것이 가장 합당하게 보인다.
'JAVA' 카테고리의 다른 글
중첩 클래스(Nested class)와 이를 정의한 클래스의 메서드(non-static)에서 사용할 때 왜 오류가 발생하는가? (0) | 2024.01.28 |
---|
[개요]
프로젝트를 진행하다 class 내에서 사용할 상수 문자열들을 관리할 때가 온다. 이들을 다른 언어에선 enum으로 의미를 갖는 집합을 만들어 사용하곤 했는데 자바에서는 귀찮은 부분이 있는 것 같다. 이를 다뤄본 후기를 적어본다.
[본문]
1. private 필드 및 getter 사용하기
private enum Role {
ADMIN("ADMIN"), // enum 은 내부에서 private 생성자를 호출하여 문자열을 초기화 한다.
USER("USER");
private final String value;
private Role(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
특정 class 내에서만 사용하는 enum은 private enum으로 만들었다. 그런데 이를 사용하려니 아래처럼 복잡한 코드가 되어 버렸다.
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.authorizeHttpRequests(auth -> auth
.requestMatchers(WHITE_LIST).permitAll()
.requestMatchers(ADMIN_LIST).hasRole(Role.ADMIN.getValue())
.requestMatchers(LOGIN_LIST).hasAnyRole(Role.ADMIN.getValue(), Role.USER.getValue())
.anyRequest().authenticated()
);
return httpSecurity.build();
}
이렇게 사용할 바에야 차라리 상수값 그대로 사용하는 게 복잡도를 더 낮추는 것처럼도 보인다. 현재는 관련 있는 문자열들을 집합으로 묶긴 했는데 이후 변경 가능성도 없는 문자열 상수라 이렇게 까지 많은 비용을 들이면서 enum을 사용할 필요는 없어 보인다.
2. public 필드 사용하기
private enum Role {
ADMIN("ADMIN"), // enum 은 내부에서 private 생성자를 호출하여 문자열을 초기화 한다.
USER("USER");
public final String value;
private Role(String value) {
this.value = value;
}
}
이처럼 사용하면 바로 Role.ADMIN 같이 꺼낼 수 있을까 했는데 ADMIN, USER라는 값은 Role이라는 타입으로 문자열이 아니었다. 사용하려면 Role.ADMIN.value와 같은 방식으로 사용해야 한다. 이는 객체지향도 깨는 것 같은데 거기에 private 필드를 사용했던 첫 번째 방법과 크게 다르지 않아 이를 선택할 이유가 없다.
3. 초기화 없이 사용하기
private enum Role {
ADMIN,
USER;
}
위와 같이 사용하면 Role.ADMIN 이라 하면 Role 타입이고, Role.ADMIN.name()이라 하면 필드의 이름을 내뱉고, Role.ADMIN.ordinal()이라 하면 초기화 되어 있는 상수값인 0을 뱉는다. 역시 이도 너무 길어져서 (1) 거의 변하지 않는 값이고 (2) 짧은 길이의 데이터인데 비슷한 의미의 집합을 만들기 위해 enum까지 사용할 이유를 느끼진 못했다.
[결론]
앞으로는 class 내에서 문자열 상수를 사용하려면 private final String ADMIN = "ADMIN";과 같이 사용할 것 같다. 같은 의미의 집합으로 묶지는 못하겠지만, 두 번 이상 사용할 수 있는 문자열을 상수 그대로 사용하기에는 재사용성이 떨어질 것 같기 때문이다. 만약 한 번만 사용한다면 굳이 필드로 뺄 필요도 없긴 할 것 같다. 이렇게 사용하다 필요에 의해 리팩토링하는 방식으로 하는 것이 가장 합당하게 보인다.
'JAVA' 카테고리의 다른 글
중첩 클래스(Nested class)와 이를 정의한 클래스의 메서드(non-static)에서 사용할 때 왜 오류가 발생하는가? (0) | 2024.01.28 |
---|