Skip to content
Go back

[Effective Java] Item 22 인터페이스는 타입을 정의하는 용도로만 사용하라

Edit page

상수 인터페이스 안티 패턴

인터페이스는 상수 정의를 하기 위해서 사용하지 말자!

상수를 인터페이스로 사용하는 것은 안티패턴이라한다. baeldung에서도 안티패턴이라 설명하고 있다.

// 안티패턴 예시
public interface PhysicalConstants {
    static final double AVOGADROS_NUMBER = 6.022_140_857e23;
    static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23;
    static final double ELECTRON_MASS = 9.109_383_56e-31;
}

클라이언트 API 노출

인터페이스를 구현한 클래스는 해당 인터페이스의 모든 상수를 public API로 노출하게 된다.

public class MyCalculator implements PhysicalConstants {
    // MyCalculator의 모든 인스턴스가 AVOGADROS_NUMBER, BOLTZMANN_CONSTANT를
    // 외부에 노출하게 됨
    public double calculate() {
        double result = AVOGADROS_NUMBER * 100;
        return result;
    }
}

// 사용 예시
MyCalculator calc = new MyCalculator();
// 이런 사용이 가능해져 버림
double value = calc.AVOGADROS_NUMBER;

이런 사용은 옳아보이지는 않다.

호환성 문제

뭐든 그렇지만 한번 상수 인터페이스를 구현하면 나중에 제거하기 어렵다. 하위 호환성을 지켜야 하기에 변경하기 쉽지 않다.

// 초기 버전
public class Calculator implements PhysicalConstants {
    // 상수 사용
    public double calculateMoles() {
        return mass / AVOGADROS_NUMBER;
    }
}

// 나중에 상수가 더 이상 필요 없어진 경우
public class Calculator {
    // 하위 호환성 때문에 제거할 수 없음!
    // 외부 코드에서 Calculator.AVOGADROS_NUMBER를 사용 중일 수 있음
}

대안

상수 유틸리티 클래스 사용

인스턴스화 할 수 없는 유틸리티 클래스를 만들어 상수를 관리.

public class PhysicalConstants {
    // 인스턴스화 방지
    private PhysicalConstants() {
        throw new AssertionError();
    }

    public static final double AVOGADROS_NUMBER = 6.022_140_857e23;
    public static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23;
    public static final double ELECTRON_MASS = 9.109_383_56e-31;
}

// 사용
public class Calculator {
    public double calculate() {
        return PhysicalConstants.AVOGADROS_NUMBER * 100;
    }
}

static import로 간결하게:

import static com.example.PhysicalConstants.*;

public class Calculator {
    public double calculate() {
        return AVOGADROS_NUMBER * 100; // 클래스명 생략 가능
    }
}

enum 타입 활용

관련된 상수들을 논리적으로 묶을 수 있다면 enum을 사용하는 방법도 있다.

public enum Weekday {
   MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

클래스 내부에 상수 정의

특정 클래스와 강하게 연관된 상수라면 그 클래스 자체에 추가하는 경우도 있다.

public class Integer {
    public static final int MIN_VALUE = -2147483648;
    public static final int MAX_VALUE = 2147483647;
    public static final int SIZE = 32;
    // ...
}

// 사용
int max = Integer.MAX_VALUE;

Edit page
Share this post on:

Previous Post
[OSTEP] 스케줄링: MLFQ(멀티 레벨 피드백 큐)
Next Post
[OSTEP]Virtualization-CPU 스케줄링