개인 프로젝트를 진행하던 도중, 상수만을 정의한 클래스를 만들 일이 있어 구글링하다가 궁금증이 생겼다.
public static final 을 붙여서 만든 상수를 한군데에 모아서 클래스를 만든다. 과연 이것만으로 충분할까? 다른 방법은 없는지 궁금해져서 자료조사를 한 후 이 글을 작성한다.
우리가 상수를 사용해야 하는 일은 꽤나 많다.
우리들은 조금 더 객체지향적으로 설계하기 위해 상수만 따로 모아서 클래스를 만들어주곤 한다.
이 클래스를 조금 더 잘 만드는 방법을 알아보자
결론
public final class Constants { // final
public static final 상수상수 = "상수상수상수";
public static final 상수 = "상수상수";
private Constants() { // private
}
빠르게 결론 먼저 보자. 클래스를 fianl 로 제한하였고 기본 생성자를 private 으로 제한하였다.
기본 생성자를 private 으로 제한하였기 때문에 구체적인 인스턴스가 존재하지 않는다는 사실이 명확해졌다.
안티 패턴?
추상 클래스를 사용하는 경우
public abstract class Constant {
public static final String 상수 = "상수상수";
}
추상클래스는 구현체가 아니니까 생성자를 자동으로 쓸 수 없잖아??
인터페이스를 사용하는 경우
public interface Constant {
String 상수 = "상수상수";
}
심지어 인터페이스는 자동으로 public static final 까지 붙여주잖아?????
또한 어디에서나 접근할 수 있으며, 인터페이스의 클래스 명을 네임스페이스로 붙이지 않고 바로 사용할 수 있다.
안티 패턴인 이유
추상 클래스와 인터페이스를 사용하는 방법 모두 안티 패턴이다.
간단한 예시와 함께 알아보자
public interface Constants {
public static final int ONE = 1;
}
public class Class1 implements Constants {
public static final int ONE = 2;
public static void main(String args[]) throws Exception {
System.out.println(ONE);
}
}
상수 인터페이스를 implements 한 클래스에 같은 상수를 가질 경우, 클래스에 정의한 상수가 사용된다.
- > 의도한 흐름대로 프로그램이 돌아가지 않을 수 있다.
implements 할 겨우 사용하지 않을 수도 있는 상수를 포함하여 모두 가져오기 때문에 계속 가지고 있어야 한다.
인터페이스를 구현해 클래스를 만든다 -> 해당 클래스의 객체로 어떤 일을 할 수 있는지 알리는 행위 -> 클라이언트를 혼동시킬 수 있다.
인터페이스 대신 public final class 로 만들고 상수 클래스를 사용해야 할 때는 import static 을 사용하자!
-> 똑같은 편의성 제공
'Java > 클린코드' 카테고리의 다른 글
Primitive Obsession (0) | 2024.07.30 |
---|