728x90
반응형
클라이언트가 클래스의 인스턴스를 얻는 전통적인 수단은 public 생성자다.
하지만 모든 프로그래머가 꼭 알아둬야 할 기법이 하나 더 있다.
클래스는 생성자와 별도로 정적 팩터리 메서드를 제공할 수 있다.
✅ 정적 팩터리 메서드는 디자인 패턴에서의 팩터리 메서드와 다르다.
👍 장점
1️⃣ 이름을 가질 수 있다.
class Member {
private String mbrId;
private String mbrPw;
public static Member ofMemberIdAndMbrPw(String mbrId, String mbrPw) {
Member member = new Member();
member.setMbrId(mbrId);
member.setMbrPw(mbrPw);
return member;
}
}
- 객체의 특성을 쉽게 묘사할 수 있다.
2️⃣ 호출될 때마다 인스턴스를 새로 생성하지는 않아도 된다.
public static Boolean valueOf(boolean bololean){
return b Boolean.TRUE : Boolean.FALSE;
}
- 인스턴스를 미리 만들어 놓거나 새로 생성한 인스턴스를 캐싱하여 재활용하는식으로 불필요한 객체 생성을 피할 수 있다.
3️⃣ 반환 타입의 하위 타입 객체를 반환할 수 있는 능력이 있다.
- 반환할 객체의 클래스를 자유롭게 선택할 수 있게하는 엄청난 유연성을 제공한다.
- 반환하는 타입을 인터페이스 타입으로 할 경우, 해당 인터페이스를 구현하는
다른 타입의 객체들을 반환할 수 있음을 말한다. (상속) - 정적 팩터리를 사용하는 클라이언트는 얻은 객체를 인터페이스만으로 다루게 된다.
4️⃣ 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.
/**
* Creates an empty enum set with the specified element type.
*
* @param <E> The class of the elements in the set
* @param elementType the class object of the element type for this enum
* set
* @return An empty enum set of the specified type.
* @throws NullPointerException if {@code elementType} is null
*/
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum<?>[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
- 예시로 EnumSet 클래스는 publi 생성자 없이 오직 정적 팩터리 메서드만 제공한다.
- 만약 원소가 64개 이하이면 원소들은 long 변수 하나로 관리하는 RegularEnumSet의 인스턴스
- 65개 이상이면 long 배열로 관리하는 JunboEnumSet의 인스턴스를 반환한다.
- 클라이언트는 이 두 클래스의 존재를 몰라도 된다.
public abstract class Discount {
public static <E extends Discount> Discount getInstance(String code){
return code.equals("1")? new RateDiscount() : new FixedDiscount();
}
}
public class FixedDiscount extends Discount{
public FixedDiscount() {
System.out.println("FixedDiscount.FixedDiscount");
}
}
public class RateDiscount extends Discount{
public RateDiscount() {
System.out.println("RateDiscount.RateDiscount");
}
}
5️⃣ 정적 팩터리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.
👎 단점
1️⃣ 상속을 하려면 public이나 protected 생성자가 필요하니 정적 팩터리 메서드만 제공하면 하위 클래스를 만들 수 없다.
- 컬렉션 프레임워크의 유틸리티 구현 클래스들은 상속할 수 없다
2️⃣ 정적 팩터리 메서드는 프로그래머가 찾기 어렵다.
- 생성자처럼 API 설명에 명확히 드러나지 않으니 샂용자는 정적 팩터리 메서드 방식 클래스를 인스턴화할 방법을 알아내야 한다.
참고 자료
Joshua Bloch, 『Effective Java 3/E』, 개앞맵시 옮김, 프로그래밍인사이트(2018)
http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788966262281&orderClick=LEa&Kc=
728x90
반응형
'Java' 카테고리의 다른 글
[Effective Java] 아이템 3. private 생성자나 열거 타입으로 싱글턴임을 보증하라. (0) | 2022.05.24 |
---|---|
[Effective Java] 아이템 2. 생성자에 매개변수가 많다면 빌더를 고려하라. (0) | 2022.05.24 |
[Java] Comparator 와 Comparable (0) | 2021.01.23 |
[Java] 컬렉션 프레임워크 (0) | 2021.01.23 |
[Java] 예외처리 (0) | 2021.01.17 |