본문 바로가기

728x90
반응형

회고/이펙티브 자바 3판

(23)
[ 아이템 5 ] 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 많은 클래스가 하나 이상의 자원에 의존한다. 맞춤법 검사기는 사전(dictionary)에 의존하는데, 이런 클래스를 정적 유틸리티 클래스(아이템4)로 구현한 모습을 가끔 볼 수 있다. *5-1 정적 유틸리티를 잘못 사용한 예 - 유연하지 않고 테스트하기 어렵다 public class SpellChecker { private static final Lexicon dictionary = ...; private SpellChecker() {} //객체 생성 방지 public static boolean isValid(String word) { ... } public static List suggestions(String typo) { ... } } 비슷하게, 싱글턴(아이템3)으로 구현하는 경우도 흔하다. *5-..
[ 아이템 4 ] 인스턴스화를 막으려거든 private 생성자를 사용하라 객체지향적으로 사용하지 않고 남용하는 경우들이 종종 있지만, 정적 메서드와 정적 필드만을 담은 클래스를 만들 수 있다. java.lnag.Math 혹은 java.lang.Arrays처럼 기본 타입 값이나 배여 관련 메서드들을 모아 놓을 수 있다. java.util.Collections처럼 특정 인터페이스를 구현하는 객체를 생성해주는 정적 팩터리 메서드를 모아놓을 수도 있다. ( 자바8에서는 이제 이런 메서드들을 인터페이스에 넣을 수 있다.) final 관련 메서드들도 모을 수 있다. ( finakl 클래스를 상속해서 하위 클래스에 메서드를 넣는 건 불가능) 정적 멤버만 담은 유틸리티 클래스는 인스턴스로 만들어 쓰려고 설계한 것이 아니다. 하지만 생성자를 명시하지 않으면 컴파일러가 자동으로 기본 생성자를 ..
[ 아이템 3 ] private 생성자나 열거 타입으로 싱글턴임을 보증하라 싱글턴이란, 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다. 예로, 함수(아이템24)같은 무상태 객체나 유일한 시스템 컴포넌트를 들 수 있다. 그런데 클래스를 싱글턴으로 만들면 이를 사용하는 클라이언트를 테스트하기거 어려울 수 있다. 타입을 인터페이스로 정의하고 구현해서 만든 싱글턴이 아니라면 mock 구현이 불가능하기 때문이다. * 3-1 public static final 필드 방식의 싱글턴 public class Elvis { public static final Elvis INSTANCE = new Elvis(); private Elvis() { ... } public void leaveTheBuilding() {} } private 생성자는 public static final 필드인 El..
[ 아이템 2 ] 생성자에 매개변수가 많다면 빌드를 고려하라
[ 아이템 1 ] 생성자 대신 정적 팩터리 메서드를 고려하라 클래스의 생성자를 얻는 전통적인 방법은 public 생성자이다. 하지만 클래스는 또한 정적 팩터리 메서드(static factory method)를 제공할 수 있다. 그 쿨래스의 인스턴스를 반환하는 정적 메서드를 뜻한다. 다음 코드는 boolean 기본 타입의 박싱 클래스(boxed class)인 Boolean의 예이다. 기본 타입인 boolean 값을 받아 Boolean객체 참조로 반환해준다. public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; } *정적 팩터리 메서드 장점 1. 이름을 가질 수 있다. 생서자는 이름을 가질 수 없어서 설명이 부실하지만, 정적 팩터리는 이름을 잘 지으면 반환될 때 특징을 쉽..
[ 아이템 55 ] 옵셔널 반환은 신중히 하라 반환값이 없을 때 과거의 방법 1. 예외를 던진다. -> 예외는 진짜 예외적인 상황에서만 사용해야 한다(아이템 69). 예외를 생성할 때 스택 추적 전체를 캡처하므로 비용도 만만치 않다. 2. 반환 타입이 객체 참조라면 null을 반환한다. -> null이 반환될 일이 절대 없다고 확신하지 않는 한) 별도의 null 처리 코드를 추가해야 한다. null 처리를 무시하고 반환된 null은 언젠가 NullPointerException이 발생할 수 있다. 새로운 대안 : Optional Optional는 null이 아닌 T 타입 참조를 하나 담거나, 혹은 아무것도 담지 않을 수 있다. 아무것도 담지 않은 옵셔널은 '비었다'고 말한다. 반대로 값을 가지고 있다면 '비지 않았다'라고 표현한다. 옵셔널은 원소를 최..
[ 아이템 54 ] null이 아닌, 빈 컬렉션이나 배열을 반환하라 일반적으로 null을 반환하는 경우는 다음과 같다. null을 반환하는 예( 금지 ) 컬렉션이 비어있으면 null을 반환한다. - 따라하지 말 것! private final List cheeseInStock = ...; /** * @return 매장 안의 모든 치즈 목록을 반환한다. * 단, 재고가 하나도 없다면 null을 반환한다. */ public List getCheeses() { return cheeseInStock.isEmpty() ? null : new ArrayList(cheeseInStock); } 재고가 없다고 해서 특별한 취급을 할 이유는 없다. 그럼에도 이 코드처럼 null을 반환해야 한다면, 이 null 상황을 처리하는 코드를 추가로 작성하도록 한다. List cheese = sho..
[ 아이템 53 ] 가변인수는 신중히 사용하라 가변인수란? 가변인수(varargs) 메서드는 명시한 타입의 인수를 0개 이상 받을 수 있따. 가변인수 메서드를 호출하면, 가장 먼저 인수의 개수와 기링가 같은 배열을 만들고 인수들을 이 배열에 저장하여 가변인수 메서드에 건네준다. 간단한 가변인수 활용 예 static int snum(int... args) { int sum = 0; for (int arg : args) sum += arg; return sum; } 인수가 1개 이상이어야 할 때도 있다. 예를 들어 최솟값을 찾는 메서드인데 인수를 0개만 받을 수 있도록 설계한 것은 좋지 않다. 인수 개수는 런타임에 배열의 길이로 알 수 있다. 잘못된 가변 인수의 사용법 인수가 1개 이상이어야 하는 가변인수 메서드 - 잘못 구현한 예! static int..

728x90
반응형