[ 이펙티브 자바 3/E ] https://www.yes24.com/Product/Goods/65551284
2장에서는 다음을 알아본다.
객체를 만들어야 할때와 만들지 말아야 할때를 구분하는 법
올바른 객체 생성 방법과 불필요한 생성을 피하는 방법
객체가 제때 파괴됨을 보장하고 파괴 전에 수행해야 할 정리 작업을 관리하는 요령
정적 팩터리 메서드 사용한 boolean boxed class
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
클래스는 클라이언트에 public 생성자 대신 정적 팩터리 메서드를 제공할 수 있다.
1. 이름을 가질 수 있다.
생성자를 사용한 경우, 매개변수와 생성자 자체 이름만으로는 반환될 객체의 특성을 제대로 설명하지 못한다.
정적 팩터리 메서드는 이름을 잘 지어 반환될 객체의 특성을 쉽게 묘사할 수 있다.
예 ) BigInteger.probablePrime
2. 호출될 때마다 인스턴스를 새로 생성하지 않아도 된다.
불변 클래스는 인스턴스를 미리 만들어 놓거나 새로 생성한 인스턴스를 캐싱하여 재활용하는 식으로 불필요한 객체 생성을 피할 수 있다.
Boolean.valueOf(boolean)
메서드는 객체를 아예 생성하지 않는다.
인스턴스 통제 클래스 : 반복되는 요청에 같은 객체를 반환, 정적 팩터리 방식의 클래스는 인스턴스를 통제 할수 있다.
=> 인스턴스를 통제하면, 클래스를 싱글턴, 인스턴스화 불가 등으로 만들 수 있다.
3. 반환 타입의 하위 타입 객체를 반환할 수 있는 능력이 있다.
반환할 객체의 클래스(해당 객체의 하위 클래스)를 자유롭게 선택 가능하다. => 유연성
이런 유연성을 이용해, 구현 클래스를 공개하지 않고, 객체 반환이 가능해 API를 작게 유지할 수 있다.
45개의 유틸리티 구현체를 제공하는 java.util.Collections 클래스 또한 정적 팩터리 메서드를 사용한다.
4. 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.
EnumSet 클래스의 경우 매개변수의 원소 갯수에 따라 서로 다른 구현체 반환한다.
(RegularEnumSet
- 64개 이하, JumboEnumSet
- 65개 이상 )
다음 릴리스에서는 또 다른 클래스의 객체를 반환해도 된다.
5. 정적 팩터리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.
이런 유연함은 서비스 제공자 프레임워크의 근간이 된다.
(제공자 = 서비스의 구현체, 클라이언트를 구현체로부터 분리)
서비스 제공자 프레임워크의 3개 핵심 컴포넌트
JDBC 의 경우, connection이 서비스 인터페이스 역할을 , DriverManger.registerDriver가 제공자 등록 API , DriverManger.getConnection이 서비스 접근 API 역할, Driver가 서비스 제공자 인터페이스 역할을 수행
1. 상속을 하려면 public, protected 생성자가 필요하니 정적 팩터리 메서드만 제공하면 하위 클래스를 만들 수 없다.
컬렉션 프레임워크 유틸리티 구현 클래스는 상속이 불가하다.
오히려 이 제약은 상속보다 컴포지션을 사요ㅇ하도록 유도하고, 불변타입으로 만들려면 제약을 지키라는 장점
2. 정적 팩터리 메서드는 프로그래머가 찾기 어렵다.
생성자와 같이 API 명세에 정확히 드러나지 않는다.
사용자는 여러 정적 팩토리 메서드가 존재하는 경우, 클래스를 인스턴스화할 수 있는 여러 방법을 스스로 학습해야 사용가능하다.