본문 바로가기
Programming/Clean Code

정적 팩토리 메서드

by peter paak 2021. 3. 6.
728x90
  • static으로 선언한 객체를 생성하는 메소드
  • 장점
    1. 가독성이 높다
    2. 객체를 캐싱할 수 있다
    3. 하위 자료형 객체를 반환할 수 있다
  • 단점
    1. 정적 팩토리 메서드만 있는 클래스는 하위 클래스를 못만든다
    2. 일반 정적 메소드와 구분하기 힘들다

1. 가독성이 높다

  • 이름으로 인스턴스의 목적을 알 수 있다
class Person {

    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 정적 팩토리 메소드
    public static Person adult() {
        return new Person("성인", 40);
    }

    // 정적 팩토리 메소드
    public static Person kid() {
        return new Person("아이", 7);
    }
}
  • Person이라는 객체의 인스턴스를 생성할 때 이름으로 생성이 가능하게 된다
Person adult = Person.adult();
Person kid = Person.kid();

2. 객체를 캐싱할 수 있다

  • immutable 객체를 캐시하여 매번 new 로 객체를 생성할 필요가 없다
  • 미리 static 변수를 생성하여 힙에 인스턴스를 생성해놓고 참조만 할 수 있다
// 0
public static final BigInteger ZERO = new BigInteger(new int[0], 0);

// 양수 1부터 16, 음수 1부터 16
private final static int MAX_CONSTANT = 16;
private static BigInteger posConst[] = new BigInter[MAX_CONSTANT+1];
private static BigInteger negConst[] = new BigInter[MAX_CONSTANT+1];

public static BigInteger valueOf(long val) {
    if (val == 0)
        return ZERO;
    if (val > 0 && val <= MAX_CONSTANT)
        return posConst[(int) val];
    else if (val < 0 && val >= -MAX_CONSTANT)
        return negConst[(int) -val];

    return new BigInteger(val);
}

3. 하위 자료형 객체를 반환할 수 있다

  • 조건에 따라 하위 객체를 반환할 수 있다
class Order {

    public static Discount createDiscount(String discountCode) {
        // 유효성 검증
        if(!isValidCode(discountCode)) {
            throw new Exception("유효하지 않은 할인코드");
        }
        // 쿠폰인 경우
        if(isUsableCoupon(discountCode)) {
                return new Coupon(1000);
        // 포인트인 경우
        } else if(isUseablePoint(discountCode)) {
                return new Point(500);
        } ...    
        throw new Exception("이미 사용한 코드");
    }
}

class Coupon extends Discount
class Point extends Discount
  • 분리하기 애매한 작은 클래스는 private class로 활용할 수 있다
    • EmptyMap 클래스는 private class객체 생성용으로 내부적으로만 사용하였다
    • EmptyMap 객체를 미리 생성하고 정적 팩토리 메소드로 Map 객체를 생성하였다
private static class EmptyMap<K,V> extends AbstractMap<K,V> implements Map

public static final Map EMPTY_MAP = new EmptyMap<>();

public static final <K,V> Map<K,V> emptyMap() {
    reurn (Map<K,V>) EMPTY_MAP;
}

출처

728x90