
아이템 1) 생성자 대신 정적 팩터리 메서드를 고려하라
아이템 2) 생성자에 매개변수가 많다면 빌더를 고려하라
package step2;
// item2 : 생성자에 대한 매개변수가 많으면 빌더를 고려하라
// 빌더 패턴 - 점층적 생성자 패턴과 자바빈즈 패턴의 장점으로 형성
public class item2 {
private final int servingSize;
private final int servings;
private final int carlories;
private final int fat;
private final int sodium;
private final int carbohyrate;
public static class Builder{
// 필수 매개변수
private final int servingSize;
private final int servings;
// 선택 매개변수 - 기본값으로 초기화
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public Builder(int servingSize, int servings){
this.servingSize = servingSize;
this.servings =servings;
}
public Builder calories(int val)
{calories = val; return this;}
public Builder fat(int val)
{fat = val; return this;}
public Builder sodium(int val)
{sodium = val; return this;}
public Builder carbohydrate(int val)
{carbohydrate = val; return this;}
public item2 build(){
return new item2(this);
}
private item2(Builder builder){
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
}
}
아이템 3) private 생성자나 열거 타입으로 싱글턴임을 보증하라
싱글턴(singleton)
- 인스턴스를 오직 하나만 생성할 수 있는 클래스
- 클래스를 싱글턴으로 만들면 이를 사용하는 클라이언트를 테스트하기 어려워질 수 있다.
종류 및 특징
package step2;
// item3 : private 생성자나 열거 타입으로 싱글턴임을 보증하라
public class item3_1 {
// public static final 필드 방식의 싱글턴
public static final item3_1 INSTANCE = new item3_1();
private item3_1(){}
public void leaveTheBuilding(){}
}
package step2;
// item3 : private 생성자나 열거 타입으로 싱글턴임을 보증하라
public class item3_2 {
// 정적 팩터리 방식의 싱글턴
public static final item3_2 INSTANCE = new item3_2();
private item3_2(){}
public static item3_2 getInstance(){return INSTANCE;}
public void leaveTheBuilding(){}
// 싱글턴임을 보장해주는 readResolve 메서드
private Object readResolve(){
// '진짜' item3_2를 만들고 가짜 item3_2는 GC에 맡긴다.
return INSTANCE;
}
}
package step2;
// item3 : private 생성자나 열거 타입으로 싱글턴임을 보증하라
public enum item3_3 {
// 열거타입 방식의 싱글턴
INSTANCE;
public void leaveTheBuilding(){}
}
아이템 4) 인스턴스화를 막으려거든 private 생성자를 사용하라
package step2;
// item 4 : 인스터스화를 막으려거든 private 생성자를 사용하라
// 인스턴스를 막을 수 없는 유틸리티 클래스
public class item4 {
// 기본 생성자가 만들어지는 것을 막는다.(인스턴스화 방지용)
private item4(){
throw new AssertionError();
}
// 나머지 코드 생략
}
추상 클래스로 만드는 것은 인스턴스화를 막을 수 없다.
→ 하위 클래스를 만들어 인스턴스화하면 된다.
해결방안 : private 생성자를 추가하면 클래스의 인스턴스화를 막을 수 있다.
아이템 5) 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
package step2;
// item5 : 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
public class item5 {
// 의존 객체 주입은 유연성과 테스트 용이성을 높여준다.
private final Lexticon dictionary;
public item5(Lexticon dictionary){
this.dictionary = Objects.requireNonNull(dictionary);
}
public boolean isValid(String word){}
public List<String> suggestions(String typo){}
}
핵심정리
- 클래스가 내부적으로 하나 이상의 자원에 의존하고, 그 자원이 클래스 동작에 영향을 준다면 싱글턴과 정적 유틸리티 클래스는 사용하지 않는 것이 좋다.
- 이 자원들을 클래스가 직접 만들게 해서도 안된다.
- 대신 자원을 생성자에 넘겨준다면 의존 객체 주입 방법은 클래스의 유연성, 재사용성, 테스트 용이성을 개선해준다.
** 이미지출처) Google yes24