# ITEM21 인터페이스는 구현하는 쪽을 생각해 설계하라
# Default Method
자바8, 기존 인터페이스에 메서드를 추가할 수 있는 방법
핵심 컬렉션 인터페이스에 디폴트 메서드가 추가 되었다.
- 주로 람다를 활용하기 위함
- 자바 라이브러리의 디폴트 메서드는 코드품질이 높고 범용적 → 대부분 잘 작동
# 주의 사항
# 불변식을 해치지 않는 디폴트 메서드 작성의 어려움
# 문제점
자바 8 의 Collection 인터페이스에 추가된 removeIf 디폴트 메서드
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean result = false;
for (Iterator<E> it = iterator(); it.hasNext(); ) {
if (filter.test(it.next())) {
it.remove();
result = true;
}
}
return result;
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
apache.commons.collections4.collection.SynchronizedCollection
- 클라이언트가 제공한 객체로 락을 거는 능력을 추가로 제공
- 모든 메서드에서 주어진 락 객체로 동기화 한 후 내부 컬렉션 객체에 위임하는 래퍼클래스
removeIf
와 맞지 않음 (effective java 3판 작성시점)- removeIf 의 구현은 동기화에 대해 모르므로 락 객체를 사용할 수 없다.
# 해결 방안
- 구현한 인터페이스의 디폴트 메서드 재정의
자바 플랫폼에 속하지 않은 제 3의 기존 컬렉션 구현체에서는 여전히 수정되지 않고 있을 수 있다.
# 디폴트 메서드는 컴파일에 성공하더라도 기존 구현체에 런타임 오류를 일으킬 수 있다.
흔한일은 아니지만 일어날 수 있다.
# 기존 인터페이스에 디폴트 메서드로 새 메서드를 추가하는 일은 꼭 필요한 경우가 아니면 피한다.
디폴트 메서드가 기존 구현체들과 충돌하지 않는지 고려한다.
새로운 인터페이스를 만드는 경우라면 유용한 수단이다.
# 디폴트 메서드는 인터페이스로부터 메서드를 제거하거나 기존 메서드의 시그니처를 수정하는 용도가 아니다.
이런 형태로 인터페이스를 변경하면 기존 클라이언트를 망가뜨리게 된다.
# 새로운 인터페이스라면 릴리스 전에 반드시 테스트를 거쳐야 한다.
인터페이스를 릴리즈 한 후의 결함 수정 가능성에 대해 기대서는 안된다.