네로개발일기

개발자 네로의 개발 일기, 자바를 좋아합니다 !

반응형

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

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

* 디폴트 메서드는 구현 클래스에 대해 아무 것도 모른채 합의없이 무작정 '삽입'될 뿐이다.
* 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
반응형
blog image

Written by ner.o

개발자 네로의 개발 일기, 자바를 좋아합니다 !