ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Item 22: Use interfaces only to define types
    독서/Effective Java 2021. 12. 26. 13:49

    인터페이스는 타입을 정의하는 용도로만 사용하라

     

    인터페이스는 구현 클래스의 인스턴스를 참조할 수 있는 타입 역할, 어떤 기능을 수행할 수 있는 지 알려주는 역할로 존재한다. 

    하지만, 그 외의 용도로 사용하려는 경우도 존재하는데, 대표적으로는 상수 인터페이스(constant interface)가 존재한다.

    해당 인터페이스는 method 없이 static final 필드로만 가득 차 있는 인터페이스를 의미한다.

    // Constant interface antipattern - do not use!
    public interface PhysicalConstants {
        // Avogadro's number (1/mol)
        static final double AVOGADROS_NUMBER = 6.022_140_857e23;
        // Boltzmann constant (J/K)
        static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23;
        // Mass of the electron (kg)
        static final double ELECTRON_MASS = 9.109_383_56e-31;
    }

    해당 인터페이스 패턴은 인터페이스를 잘못 사용한 예이다.

    클래스 내부에서 사용하는 상수들의 경우 내부 구현에 해당하고, 이를 인터페이스에서 구현하는 것은 내부 구현을 외부에 노출하는 행위이다. 또한, 해당 상수 구현들의 경우 사용자가 알 필요, 의미가 전혀 없는데다 반대로 사용자에게 혼선을 주는, 특히 클라이언트 코드가 해당 상수를 사용하게 되는 순간 코드 자체가 이 상수들에 종속되는 위험한 구현 방법이다.

    추가적으로 이미 공개한 API의 내에 속하고, 더 쓰지 않더라도 바이너리 호환성 때문에 계속해서 구현해야 한다.

    더보기

    Underscore 활용

    위의 예시에서 Underscore(_)를 숫자를 훨씬 쉽게 읽을 수 있도록 사용했다.

    해당 방식은 Java 7부터 가능해졌고, Underscore를 사용한다고 해도 수의 값에 영향을 미치지 않는다.

     

    더 나은 선택지들

    여러 방법이 있고, 개인적으로는 Enum type으로 만들어 사용하는 편을 선호한다.

    Enum type으로 나타내기 적합한 상수라면 Enum으로 만들어 공개하자(Item 34).

    인스턴스화할 수 없는 utility class로 담아 공개하자(Item 4).

    // 상수 유틸리티 클래스
    public class PhysicalConstants {
        // 인스턴스화를 방지하기 위한 private constructor
        private PhysicalConstants() { } 
        public static final double AVOGADROS_NUMBER = 6.022_140_857e23;
        public static final double BOLTZMANN_CONST = 1.380_648_52e-23;
        public static final double ELECTRON_MASS = 9.109_383_56e-31;
    }
    
    // 정적 임포트(static import)를 사용해 클래스명 없이 바로 사용할 수 있다.
    import static com.effectivejava.science.PhysicalConstants.*;
    public class Test {
        double atoms(double mols) {
        return AVOGADROS_NUMBER * mols;
        }
    }

    정리

    인터페이스는 타입을 정의하는 용도로만 사용하자. 상수 공개용 수단으로 사용하기에는 좋은 대안이 너무나도 많다.

    댓글

Designed by Tistory.