티스토리 뷰

728x90
반응형

인터페이스 상수

  1. 인터페이스 상수 ?

  2. 인터페이스 상수는 Anti-Pattern

  3. References

인터페이스 상수 ?

인터페이스 내에 선언된 변수는 무조건 public static final 로 선언 된다.

 class A {
   public static final int MON = 1;
   public static final int TUE = 2;
   public static final int WED = 3;
 }

클래스 내의 상수

 interface A {
   int MON = 1, TUE = 2, WED = 3;
 }

인터페이스 내의 상수

[ 출처 ] : https://codedragon.tistory.com/2526

따라서 위의 두 코드는 완전히 동일한 의미이다.

인페이스 상수는 Anti-Pattern

처음 인터페이스 상수에 대해 검색을 한 것은 클래스 내의 상수와 인터페이스 내의 상수가 메모리 상의 혹은 사용하는 측면에서 어떤 차이점을 가지는지 알고싶어 검색을 하였다.

일단 위에서 보는것과 같이 둘 다 public static final 로 인식되기에 차이는 없어 보인다.

하지만 여러 의견들이 인터페이스 상수는 Anti-Pattern 이라는 주장을 하고 있다.

Anti-Pattern

사용을 지양해야 하는 디자인 패턴.

( Ex. God Object, Spaghetti Code, Hard Code ... )

그 내용을 살펴보면 이렇다.

  1. 사용하지 않는 상수변수가 네임스페이스를 오염시킬 수 있습니다.

  2. 만약 다음 릴리즈때 해당 상수가 필요 없어도 이전 버전과의 호환성을 유지하려면 해당 상수는 영원히 인터페이스에 남아 있어야 합니다.

  3. 해당 상수가 어디에서 오는지를 쉽게 보여주는 IDE가 없다면 해당 상수를 찾기 위해 추적하는 시간은 오래걸릴 수 있습니다.

  4. 인스턴스를 나타내는 인터페이스 변수는 인터페이스 이름 자체보다 유용하지 않습니다.

( Method 가 없기 때문에 )

  1. 외부에 API또는 라이브러리 형태로 제공할때 구현방식이 드러나게 됩니다.

  2. 개발자가 클래스에 상수를 추가할 때 구현된 인터페이스를 확인하지 않으면 상수의 값이 변경 될 수도 있다.

[ 출처 ] : https://en.wikipedia.org/wiki/Constant_interface

6번에서 설명하는 내용은 이렇다.

 public interface Constants {
 
  public static final int CONSTANT = 1;
 }
 
 public class Class1 implements Constants {
 
  public static final int CONSTANT = 2; // *
 
  public static void main(String args[]) throws Exception {
  System.out.println(CONSTANT);
  }
 }

위와 같이 Constants 를 implents 한 Class1 에서 CONSTANT 상수를 정의하고 있는데도 경고나 오류 없이 컴파일이 된다. 출력 결과도 2 를 출력한다.

그렇다면 Anti-Pattern 을 피하기 위해 상수를 어떤 방식으로 써야 할까 ?

위키에서는 아래와 같은 방법을 알려주고 있다.

 public final class Constants {
 
  private Constants() {
  // restrict instantiation
  }
 
  public static final double PI = 3.14159;
  public static final double PLANCK_CONSTANT = 6.62606896e-34;
 }

class 를 final 로 선언하여 상속을 방지하고, 생성자를 private 으로 선언해 준다.

( 명시적 생성자가 없을 경우, 묵시적 생성자가 생김 - public )

위와 같이 선언해 두고 Java5 부터 지원하는 import static 를 활용해 해당 상수에 접근한다.

 import static Constants.PLANCK_CONSTANT;
 import static Constants.PI;
 
 public class Calculations {
 
  public double getReducedPlanckConstant() {
  return PLANCK_CONSTANT / (2 * PI);
  }
 }

다른 글에서 본 경우인데, 어떤 개발자는 인터페이스 상수를 정의해 두고 클래스에 implement 하여 해당 상수에 접근시, 접근 지정자를 사용하지 않고 전역변수처럼 사용하려고 인터페이스 상수를 이용한다고 보았다.

위의 import static 을 활용하면 같은 방식으로 접근이 가능하다.

 // Constants 클래스의 PI 상수 접근
 return Constants.PI;
 // import static 후 Constants 클래스의 PI 상수 접근
 return PI;

References

https://codedragon.tistory.com/2526

https://boxfoxs.tistory.com/317

https://lng1982.tistory.com/113

https://en.wikipedia.org/wiki/Constant_interface


반응형
공지사항
최근에 올라온 글