본문 바로가기
Java/Effective Java 3E

[이펙티브자바 3판] ITEM22. 인터페이스는 타입을 정의하는 용도로만 사용하라

by 잭피 2020. 9. 28.
반응형

이번장의 핵심은...

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

상수 공개용 수단으로 사용하지 말자


타입 역할

인터페이스는 자신을 구현한 클래스의 인스턴스를 참조할 수 있는 타입 역할이다

자신의 인스턴스로 무엇을 할 수 있는지 클라이언트에 얘기해주는 것이다

인터페이스는 오직 이 용도로만 사용해야 한다

 

상수 인터페이스

메서드 없이, 상수를 뜻하는 static final 필드로만 가득 찬 인터페이스를 말한다

이 상수들을 사용하려는 클래스에서는 정규화된 이름을 쓰는 걸 피하고자 그 인터페이스를 구현한다

인터페이스를 잘못 사용한 예를 보자 (상수 인터페이스 안티 패턴)

// 상수 인터페이스 안티패턴 - 사용금지!
public interface PhysicalConstants {
	static final double AVOGADROS_NUMBER = 6.022_140_...;
	static final double BOLTZM... = 1.380_648...;
	static final double ELECTRON... = 9,109_383..;
}	

클래스 내부에서 사용하는 상수는 외부 인터페이스가 아니라 내부 구현에 해당한다

상수 인터페이스를 구현하는 것은 이 내부 구현을 클래스의 API로 노출하는 행위이다 

사용자에게 혼란을 주고, 클라이언트가 내부 구현에 해당하는 이 상수들에 종속하게 된다

 

이 상수들을 쓰지 않게 되더라도 바이너리 호환성을 위해 여전히 상수 인터페이스를 구현하고 있어야 한다

(바이너리 호환성 : 인터페이스에 메서드를 추가했을 때 추가된 메서드를 호출하지 않는 한 문제가 일어나지 않는 것)

 

final이 아닌 클래스가 상수 인터페이스를 구현한다면 모든 하위 클래스의 이름 공간이 그 인터페이스가 정의한 상수들로 오염되어 버린다

 

ObjectStreamConstants 등 자바 플랫폼 라이브러리에도 잘못 활용한 상수 인터페이스가 몇 개 있음

 

상수 유틸리티 클래스

상수를 공개할 목적이라면 더 합당한 선택지가 몇 가지 있다

 

특정 클래스나 인터페이스와 강하게 연관된 상수라면 그 클래스나 인터페이스 자체에 추가해야 한다

ex) Integer, Double에 선언된 MIN_VALUE, MAX_VALUE 상수

 

열거 타입으로 나타내기 적합한 상수라면 열거 타입으로 만들어 공개한다

 

위 2개의 방법으로 안된다면 인스턴스화할 수 없는 유틸리티 클래스를 담아 공개하자

앞의 PhysicalConstants의 유틸리티 클래스 버전

public class PhysicalConstants {
	private PhysicalConstants() {} // 인스턴스화 방지
	public static final double AVOGADROS_NUMBER = 6.022_140_...;
	public static final double BOLTZM... = 1.380_648_...;
	public static final double ELECTRON... = 9,109_383_..;
}

숫자 리터럴에 사용한 밑줄(_)은 읽기를 훨씬 편하게 해준다 (자바 7부터 허용)

5자리 이상이면 밑줄을 사용하는 걸 고려해보자(10진수는 3자리씩 묶어주는 것이 좋다)

 

반응형

댓글