728x90
반응형
cf) Item.51 : 매개변수 타입으로 클래스가 아닌, 인터페이스를 사용하라
→ 객체는 클래스가 아닌 인터페이스로 참조하라로 확장
적합한 인터페이스만있다면 매개변수뿐 아니라, return, 변수, 필드를 전부 인터페이스 타입으로 선언하자
- 실제 클래스를 사용해야 할 상황은 오직 생성자로 생성할 때뿐이다.
인터페이스를 타입으로 사용하는 습관은 프로그램을 훨씬 유연하게 만들어 준다
// Good
Set<Son> sonSet = new LinkedHashSet<>();
Set<Son> sonSet = new HashSet<>(); //유연하게 변경가능
// Bad
LinkedHashSet<Son> sonSet = new LinkedHashSet<>();
- 인터페이스를 타입으로 사용하면 이후 구현 클래스를 교체할 때 새 클래스의 생성자(혹은 다른 정적 팩토리)를 호출만 하면 된다.
- 다른 코드는 손대지 않고 교체가 가능하다
인터페이스를 타입으로 사용할 때 주의할 점
- 인터페이스의 일반 규약 외의 특별한 기능에 의존하고 있다면, 새로운 클래스도 반드시 동일한 기능을 제공해야한다.
- ex) LinkedHashSet의 순서 정책을 가정하고 동작하는 상황 :
- HashSet으로 바뀌면 반복자의 순회 순서를 보장하지 않음
- ex) LinkedHashSet의 순서 정책을 가정하고 동작하는 상황 :
구현 타입을 바꾸는 상황
기존의 코드보다 성능을 높이거나 새로운 기능을 제공할 수 있을 때
Map<Member> memberMap = new HashMap<>();
// EnumMap 변경을 통해 속도 증가 및 순회 순서를 키의 순서로 보장
// 단, EnumMap은 키가 열거 타입일 때만 사용 가능
Map<Member> memberMap = new EnumMap<>();
//Member가 열거 타입이 아니라면?
//LinkedHashMap을 통해 비슷한 성능을 끌어올리며 순회 순서를 예측 가능하게 보장
Map<Member> memberMap = new LinkedHashMap<>();
Q. 선언 타입과 구현 타입을 동시에 바꿀 수 있으니, 변수를 구현 타입으로 선언해도 괜찮지 않나요??
- 클라이언트에서 기존 타입에서만 제공하는 메서드를 사용하거나, 기존 타입을 사용해야만 하는 다른 메서드에 해당 인스턴스를 넘겼다면 컴파일러가 되지 않는 문제가 발생한다.
- 따라서 변경 최소화, 에러 발생 가능성 줄이기 등을 고려하여 변수를 인터페이스 타입으로 선언하면 이런 일이 발생하지 않는다.
클래스 참조를 해야할 경우
- 적합한 인터페이스가 없다면 당연히 클래스 참조를 해야 한다.
- 값 클래스
- String, BigInteger와 같은 값 클래스는 여러가지로 구현할 수 있다고 생각하고 설계하는 일은 거의 없다.
- 따라서 final인 경우가 많고 인터페이스가 별도로 존재하는 경우도 드물다.
- 이런 값 클래스는 매개변수, 변수, 필드, 반환 타입으로 사용해도 무방하다.
- 클래스 기반으로 작성된 프레임워크 객체
- ex) OutputStream 등 java.io 패키지의 여러 클래스가 해당 부류에 속한다.
- 프레임워크가 제공하는 클래스 기반 객체라도 특정 구현 클래스보다는 기반(추상) 클래스를 참조하자
- 인터페이스에는 없는 특별한 기능을 제공하는 클래스 (남발해선 X)
- 특별한 기능이 꼭 필요한 경우 최소한의 범위 내에서 클래스 참조를 사용해도 된다.
- ex) PriorityQueue 클래스는 Queue 인터페이스에는 없는 comparator 메서드를 제공하는데 이런 추가 메서드가 필요한 경우에만 사용하자
정리
- 클래스보다는 인터페이스, 추상 클래스를 참조하도록하자
- 적합한 인터페이스가 없다면 클래스의 계층구조 중 필요 기능을 만족하는 가장 덜 구체적인(상위의) 클래스를 타입으로 사용하자
728x90
반응형
'책 > Effective Java' 카테고리의 다른 글
문자열 연결은 느리니 주의하라 (0) | 2022.05.15 |
---|---|
다른 타입이 적절하다면 문자열 사용을 피하라 (0) | 2022.05.15 |
박싱된 기본 타입 vs 기본 타입 (0) | 2022.05.14 |
정확한 답과 계산을 해야한다면 float와 double은 피하라 (0) | 2022.05.14 |
메서드 참조 (Method Reference) (0) | 2022.03.20 |