[Effective Java/아이템21] 인터페이스는 구현하는 쪽을 생각해 설계하라.
2021. 12. 8. 22:07
반응형
# 인터페이스는 구현하는 쪽을 생각해 설계하라.
생각할 수 있는 상황에서 불변식을 해치지 않는 디폴트 메서드 작성은 어렵다.
* 디폴트 메서드는 구현 클래스에 대해 아무 것도 모른채 합의없이 무작정 '삽입'될 뿐이다.
* Java8: 컬렉션 인터페이스 다수에 디폴트 메서드 추가
* 범용적으로 구현되어 있지만, 모든 구현체와 어울리는 것은 아니다.
## 1. 기존 인터페이스에 default 메서드를 추가함으로써 발생하는 위험
모든 상황에서 불변식을 해치지 않는 디폴트 메서드를 작성하기란 어렵다.
- 자바 8부터 Collection 인터페이스에 removeIf() 디폴트 메서드 추가
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
- 람다를 활용하기 위해 추가된 메서드
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("test");
list.add("test2");
list.add("java Spring");
list.add("java Spring Data JPA");
SynchronizedCollection<String> sc = SynchronizedCollection.synchronizedCollection(list);
Predicate<String> startJava = s-> s.startsWith("java");
sc.remove("test"); //SynchronizedCollection 가 재정의한 remove() 메서드 호출
sc.removeIf(startJava::evaluate); // Collection 에 정의된 removeIf() 디폴트 메서드 호출
}
- SynchronizedCollection 클래스는 말 그대로 멀티 스레드 환경에서 안정성을 보장해주는 클래스
- java8 이후 추가된 removeIf 디폴트 메서드를 재정의하지 않았기 때문에 멀티 스레드 환경에서 실행하면 예기치 못한 결과 발생
## 정리
- 디폴트 메서드라는 도구가 생겼더라도 인터페이스를 설계할 때는 세심한 주의를 기울여야 한다.
- 새로운 인터페이스라면 릴리즈 전에 반드시 테스트를 거쳐야 한다.
- 인터페이스를 릴리즈한 후라도 결함을 수정하는게 가능한 경우도 있겠지만, 그 가능성에 기대서는 안된다.
728x90
반응형
'dev book > Effective Java' 카테고리의 다른 글
[Effective Java/아이템23] 태그 달린 클래스보다는 클래스 계층 구조를 활용하라. (0) | 2021.12.10 |
---|---|
[Effective Java/아이템22] 인터페이스는 타입을 정의하는 용도로만 사용하라. (0) | 2021.12.09 |
[Effective Java/아이템20] 추상 클래스보다는 인터페이스를 우선하라. (0) | 2021.12.07 |
[Effective Java/아이템19] 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라. (0) | 2021.11.19 |
[Effective Java/아이템18] 상속보다는 컴포지션을 사용하라. (0) | 2021.11.18 |
Written by ner.o
개발자 네로의 개발 일기,
자바를 좋아합니다 !
댓글 개