[Effective Java/아이템21] 인터페이스는 구현하는 쪽을 생각해 설계하라.

[Effective Java/아이템21] 인터페이스는 구현하는 쪽을 생각해 설계하라.

# 인터페이스는 구현하는 쪽을 생각해 설계하라.

생각할 수 있는 상황에서 불변식을 해치지 않는 디폴트 메서드 작성은 어렵다.

* 디폴트 메서드는 구현 클래스에 대해 아무 것도 모른채 합의없이 무작정 '삽입'될 뿐이다.

* Java8: 컬렉션 인터페이스 다수에 디폴트 메서드 추가

* 범용적으로 구현되어 있지만, 모든 구현체와 어울리는 것은 아니다.

## 1. 기존 인터페이스에 default 메서드를 추가함으로써 발생하는 위험

모든 상황에서 불변식을 해치지 않는 디폴트 메서드를 작성하기란 어렵다.

- 자바 8부터 Collection 인터페이스에 removeIf() 디폴트 메서드 추가

default boolean removeIf(Predicate filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator each = iterator(); while (each.hasNext()) { if (filter.test(each.next())) { each.remove(); removed = true; } } return removed; }

- 람다를 활용하기 위해 추가된 메서드

public static void main(String[] args) { List list = new ArrayList<>(); list.add("test"); list.add("test2"); list.add("java Spring"); list.add("java Spring Data JPA"); SynchronizedCollection sc = SynchronizedCollection.synchronizedCollection(list); Predicate startJava = s-> s.startsWith("java"); sc.remove("test"); //SynchronizedCollection 가 재정의한 remove() 메서드 호출 sc.removeIf(startJava::evaluate); // Collection 에 정의된 removeIf() 디폴트 메서드 호출 }

- SynchronizedCollection 클래스는 말 그대로 멀티 스레드 환경에서 안정성을 보장해주는 클래스

- java8 이후 추가된 removeIf 디폴트 메서드를 재정의하지 않았기 때문에 멀티 스레드 환경에서 실행하면 예기치 못한 결과 발생

## 정리

- 디폴트 메서드라는 도구가 생겼더라도 인터페이스를 설계할 때는 세심한 주의를 기울여야 한다.

- 새로운 인터페이스라면 릴리즈 전에 반드시 테스트를 거쳐야 한다.

from http://frogand.tistory.com/96 by ccl(A) rewrite - 2021-12-08 22:27:46