1. 생성자 대신 정적 팩터리 메서드를 고려하라
정적 팩터리 메서드란
클래스의 인스턴스를 반환하는 팩터리 메서드
팩터리 메서드가 생성자보다 좋은 장점 다섯 가지
- 이름을 가질 수 있다.
- 생성자에 넘기는 매개변수와 생성자 자체만으로는 반환될 객체의 특성을 정확히 이해할 수 없다.
- 정적 팩터리 메서드는 이름만 잘 지으면 반환될 객체의 특성을 쉽게 묘사할 수 있다.
- 호출될 때마다 인스턴스를 새로 생성하지는 않아도 된다.
- 인스턴스를 미리 만들어 놓거나 인스턴스를 캐싱하여 재활용하는 방식으로 객체 생성을 피할 수 있다.
- 인스턴스를 철저히 통제할 수 있는 클래스가 될 수 있음.
- 반환 타입의 하위 타입 객체를 반환할 수 있는 능력이 있다.
- 반환할 객체의 클래스를 선택할 수 있는 유연성이 있다.
- 자바 8 전에는 인터페이스에 정적 메서드를 선언할 수 없었다. 그렇기 때문에 이름이 “Type”인 인터페이스를 반환하는 정적 메서드가 필요하면, “Types”라는 동반 클래스를 만들어 그 안에 정의하는 것이 관례였다.
- 자바 8부터는 인터페이스가 정적 메서드를 가질 수 없다는 제한이 풀렸기 때문에 인스턴스화 불가 동반 클래스를 둘 이유가 별로 없다. 동반 클래스에 두었던 public 정적 멤버들 상당수를 그냥 인터페이스에 두면 되는것이다.
- 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.
- 반환 타임의 하위 타입이기만 하면 어떤 클래스의 객체를 반환하든 상관없다.
- 클라이언트는 그 클래스들의 정체를 몰라도 된다.
- 정적 팩터리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.
- 서비스 제공자 프레임워크를 만드는 근간이 된다.
단점
- 상속을 하려면 public이나 protected 생성자가 필요하니 정적 팩터리 메서드만 제공하면 하위 클래스를 만들 수 없다.
- 정적 팩터리 메서드는 프로그래머가 찾기 어렵다.
- 생성자처럼 API 설명에 명확히 드러나지 않으니.
2. 생성자에 매개변수가 많다면 빌더를 고려하라
클래스에 매개변수가 많다면..?
프로그래머들은 이럴 때 매개변수를 하나씩 늘려가며 모든 멤버 변수를 가지는 생성자들을 만들곤 했다. ⇒ 점층적 생성자 패턴
매개변수가 많아지면 클라이언트 코드를 작성하거나 읽기 어렵다.
또는 매개변수가 없는 생성자로 객체를 생성한 후 Setter로 매개변수를 채우는 방법을 사용함 ⇒ 자바빈즈 패턴
자바빈즈 패턴의 심각한 결함은 객체 하나를 만드려면 메서드를 여러개 호출해야 하고, 객체가 완전히 생성되기 전까지는 일관성이 무너진다.
이러한 단점을 완하하고자 생성이 끝난 객체를 수동으로 “얼리고” 얼리기 전에는 사용할 수 없도록 하기도 한다.
빌더 패턴의 등장