아이템21. 인터페이스는 구현하는 쪽을 생각해 설계하라
2022-01-27 00:00:00
# Effective_Java
- 디폴트 메서드에 대한 이야기…
- 생각할 수 있는 모든 상황에서 불변식을 해치지 않는 디폴트 메서드를 작성하기란 어려운 법이다.
Collection 인터페이스에 있는 removeIf 메서드 예시
1 | import java.util.Iterator; |
- predicate 함수가 true를 반환하는 모든 원소를 제거하는 메서드
- SynchronizedCollection 클래스는 클라이언트가 제공한 객체로 락을 거는 능력이 제공되는데
removeIf를 자바8과 사용한다면 모든 메서드 호출을 알아서 동기화해주지 못하게 된다. - removeIf의 구현은 동기화에 관해 아무것도 모르기에 락 객체를 사용할 수 없다.
- 따라서 SynchronizedCollection 인스턴스를 여러 스레드가 공유하는 환경에서 한 스레드가 removeIf를 호출하면 예외발생할 것임.
예방책?
- 자바 플랫폼 라이브러리에서 이런 문제를 예방하기 위한 조치
- 구현한 인터페이스의 디폴트 메서드를 재정의하고, 다른 메서드에서는 디폴트 메서드를 호출하기 전에 필요한 작업을 수행하도록 했다.
- 하지만 자바 플랫폼에 속하지 않은 제3의 기존 컬렉션 구현체들은 이런 변화에 맞춰 수정될 기회가 없어서 수정이 안 된 것도 있다 한다.
디폴트 메서드
- 디폴트 메서드는 컴파일에 성공해도 기존 구현체에 런타임 오류를 일으킬 수 있다.
- 꼭 필요한 경우가 아니면 피하자
- 디폴트 메서드라는 도구가 생겼더라도 인터페이스를 설계할 때는 여전히 세심한 주의를 기울여야 한다.
- 새로운 인터페이스라면 릴리스 전에 반드시 테스트를 거쳐야 한다.
- 인터페이스를 배포한 후라도 결함을 수정하는게 가능한 경우도 있겠지만, 절대 그 가능성에 기대서는 안 된다.