목록모던 자바 인 액션 (19)
초보개발자 긍.응.성
자바 8에서는 기본 구현을 포함하는 인터페이스를 정의하는 두 가지 방법을 제공한다. 첫 번째는 인터페이스 내부에 정적 메서드를 사용하는 것이다. 두 번째는 인터페이스의 기본 구현을 제공할 수 있도록 디폴트 메서드 기능을 사용하는 것이다. 결과적으로 기존 인터페이스를 구현하는 클래스는 자동으로 인터페이스에 추가된 새로운 메서드의 디폴트 메서드를 상속받게 된다. 이렇게 하면 기존의 코드 구현을 바꾸도록 강요하지 않으면서도 인터페이스를 바꿀 수 있다. 호환성 ✨ 바이너리 호환성 : 뭔가를 바꾼 이후에도 에러 없이 기존 바이너리가 실행될 수 있는 상황. 소스 호환성 : 코드를 고쳐도 기존 프로그램을 성공적으로 재컴파일할 수 있는 상황. 동작 호환성 : 코드를 바꾼 다음에도 같은 입력값이 주어지면 프로그램이 같은..
자바 8 이전의 날짜와 시간 API의 문제들 Date 클래스는 직관적이지 못하며 자체적으로 시간대 정보를 알고 있지 않다 Date를 deprecated 시키고 등장한 Calendar 클래스 또한 쉽게 에러를 일으키는 설계 문제를 갖고 있다 Date와 Calendar 두 가지 클래스가 등장하면서 개발자들에게 혼란만 가중되었다. 날짜와 시간을 파싱하는데 등장한 DateFormat은 Date에만 지원되었으며, 스레드에 안전하지 못했다. Date와 Calendar는 모두 가변 클래스이므로 유지보수가 아주 어렵다. LocalDate, LocalTime, Instant, Duration, Period 클래스 java.time 패키지는 LocalDate, LocalTime, LocalDateTime, Instant,..
값이 없는 상황을 어떻게 처리할까? 보수적인 자세로 NullPointerException 줄이기 필요한 곳에 다양한 null 확인 코드를 추가해서 NPE 문제를 해결한다. 변수에 접근할 때마다 중첩된 if가 추가되면서 코드 들여 쓰기 수준이 증가한다. 이와 같은 반복 패턴(recurring pattern) 코드를 *깊은 의심(deep doubt)*이라 부른다. 다른 방법으로 중첩 if 블록을 없애고 둘 이상의 출구를 두는 방식이 있다. 하지만 이와 같은 경우 출구 때문에 유지보수가 어려워질 수 있다. null 때문에 발생하는 문제 에러의 근원 : NPE는 자바에서 가장 흔하게 발생하는 에러이다. 코드를 어지럽힌다 : 중첩된 null 확인 코드를 추가해야 하므로 null 때문에 코드 가독성이 떨어진다. 아..
도메인 전용 언어 (domain-specific language, DSL) 특정 비즈니스 도메인의 문제를 해결하려고 만든 언어 특정 비스니스 도메인을 인터페이스로 만든 API 도메인을 표현할 수 있는 클래스와 메서드 집합이 필요하다 DSL의 장점 간결함 : API는 비즈니스 로직을 간편하게 캡슐화하므로 반복을 피할 수 있고 코드를 간결하게 만들 수 있다. 가독성 : 도메인 영역의 용어를 사용하므로 비 도메인 전문가도 코드를 쉽게 이해할 수 있다. 다양한 조직 구성원 간에 코드와 도메인 영역이 공유될 수 있다. 유지보수 : 잘 설계된 DSL로 구현한 코드는 쉽게 유지 보수하고 바꿀 수 있다. 높은 수준의 추상화 : DSL은 도메인과 같은 추상화 수준에서 동작하므로 도메인의 문제와 직접적으로 관련되지 않은 ..
가독성과 유연성을 개선하는 리팩터링 코드 가독성 개선 익명 클래스를 람다 표현식으로 리팩터링하기 익명 클래스에서 this는 익명 클래스 자신을 가리키지만 람다에서 this는 람다를 감싸는 클래스를 가리킨다. 익명 클래스는 감싸고 있는 클래스의 변수를 가릴 수 있다. 익명 클래스는 인스턴스화할 때 명시적으로 형식이 정해지는 반면 람다의 형식은 콘텍스트에 따라 달라진다. 람다 표현식을 메서드 참조로 리팩터링 하기 명령형 데이터 처리를 스트림으로 리팩터링 하기 코드 유연성 개선 람다 표현식을 이용하면 동작 파라미터화(behavior parameterzation)를 쉽게 구현할 수 있다. 람다 표현식을 사용하기 위해 함수형 인터페이스 적용해야 한다. 조건부 연기 실행 : 코드 내부에 제어 흐름문이 복잡하게 얽힌..
컬렉션 팩토리 기존 작은 컬렉션을 만드는 팩토리 메서드로는 Arrays.asList()가 존재했다. 고정 크기의 리스트를 만들었으므로 요소를 갱신할 순 있지만 새 요소를 추가하거나 요소를 삭제할 순 없다. 예로 요소 추가 시 UnsupportedOperationException이 발생한다. 리스트는 이렇게 팩토리 메서드라고 존재했지만 집합의 경우 리스트를 인수로 받는 HashSet 생성자를 사용하거나 스트림 API를 사용하는 방법이 존재했다. Set elems1 = new HashSet(Arrays.asList("e1","e2","e3")); Set elems2 = Stream.of("e1","e2","e3").collect(toSet()); 두 방법 모두 매끄럽지 못하며 내부적으로 불필요한 객체 할당을..