본문 바로가기
개발 공부/Java

이펙티브 자바 아이템 22 - 인터페이스는 타입을 정의하는 용도로만 사용하라 - 핵심 정리

by 개발인생 2022. 11. 30.
반응형

아이템 22 - 인터페이스는 타입을 정의하는 용도로만 사용하라 - 핵심 정리

이 글은 백기선 님의 이펙티브 자바 강의와 이펙티브 자바 3 / E 편을 참고하여 작성하였습니다.

public interface PhysicalConstants {
    // 아보가드로 수 (1/몰)
    static final double AVOGADROS_NUMBER   = 6.022_140_857e23;

    // 볼츠만 상수 (J/K)
    static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23;

    // 전자 질량 (kg)
    static final double ELECTRON_MASS      = 9.109_383_56e-31;
}

위와 같이 인터페이스를 상수를 정의하는 용도 로 사용하는 경우가 있다.

public class MyClass implements PhysicalConstants {

    public static void main(String[] args) {
        System.out.println(BOLTZMANN_CONSTANT);
    }
}

상수를 정의한 인터페이스를 어떤 클래스가 구현하게 된다면 그 안에서 상수들을 아무런 네임스페이스 없이 참조해서 사용할 수 있다.

네임스페이스 없이 쓰고자 이런 패턴을 사용할 수 있지만 권장하는 방법이 아니다.

인터페이스의 원래 의도를 오염시키기 때문이다.

인터페이스의 가장 중요한 의도는 타입을 정의 하는 것이다.

설계적인 측면에서 상수만 정의해 놓은 인터페이스의 타입으로 사용하기에는 부적절하다.

인터페이스에 정의된 상수들은 클래스의 내부에서 사용하기 위한 클래스의 내부 정보에 해당한다.

클래스의 내부 정보가 인터페이스를 통해 공개된 것이기 때문에 캡슐화 가 깨지게된다.

public class MyClass implements PhysicalConstants {

    public static void main(String[] args) {
       PhysicalConstants myClass = new MyClass();
    }
}

위와 같이 상수를 정의하기 위한 인터페이스가 클라이언트에 혼란을 줄 수도 있다.

만약 특정한 클래스에서 사용할 상수라면 해당 클래스에 선언하는게 적절하다.

인터페이스에 있어야 한다면 상수를 선언해도 되지만 가급적이면 피하는 것이 좋다.

// 상수 유틸리티 클래스
public final class PhysicalConstants {
  private PhysicalConstants() { }  // 인스턴스화 방지

  // 아보가드로 수 (1/몰)
  public static final double AVOGADROS_NUMBER = 6.022_140_857e23;

  // 볼츠만 상수 (J/K)
  public static final double BOLTZMANN_CONST  = 1.380_648_52e-23;

  // 전자 질량 (kg)
  public static final double ELECTRON_MASS    = 9.109_383_56e-31;
}

여러 클래스에서 공용으로 사용되는 상수라면 인스턴스를 만들 수 없는 유틸리티성 클래스 에 모아두는 걸 권장한다.

상속을 받을 수 없고 클래스의 참조를 통해서 상수를 사용할 수 있도록 만든다.

인터페이스는 implements 를 막을 순 없지만 클래스는 상속을 막을 수 있다.

반응형

댓글