본문 바로가기

PROGRAMMING LANGUAGE/자바

이펙티브 자바 (1).생성자 대신 정적 팩토리 메서드를 고려하라

정적 팩터리 메서드의 장점

1.이름을 가질 수 있다.

생성자는 이름을 가질 수 없기 때문에 생성자 매개변수로 같은 데이터 타입의 다른 필드를 주고 싶을 때 불편하다.

이 때 이름을 가질 수 있는 정적 팩터리 메서드를 사용할 수 있다.

public class Order {

    private boolean prime;

    private boolean urgent;

    private Product product;

   /* public Order(Product product, boolean prime){
        this.product = product;
        this.prime = prime;
    }

    public Order(boolean urgent, Product product){
        this.product = product;
        this.urgent = urgent;
    }*/

    public static Order primeOrder(Product product){
        Order order = new Order();
        order.prime = true;
        order.product = product;
        return order;
    }

    public static Order urgentOrder(Product product){
        Order order = new Order();
        order.urgent = true;
        order.product = product;
        return order;
    }

}

 

 

2. 호출될 때마다 인스턴스를 새로 생성하지는 않아도 된다.

정적 팩토리 메서드를 사용하면 생성자를 private으로 접근 불가능하게 만들고 이미 만들어둔 인스턴스를 리턴하도록 만들어줄 수 있다.생성자를 public 접근제한자로 선언하는 순간 외부에서 인스턴스를 생성할 수 있게 된다.

 

정적 팩토리 메서드를 사용하면 생성자를 private으로 접근 불가능하게 만들고 이미 만들어둔 인스턴스를 리턴하도록 만들어줄 수 있다.

 

public class Settings {

    private boolean useAutoSteering;

    private boolean useABS;

    private Difficulty difficulty;

    private Settings(){}

    private static final SettingsSETTINGS= new Settings();

    public static Settings newInstance(){
        returnSETTINGS;
    }


}

 

 

3. 반환 타입의 하위 타입 객체를 반환할 수 있는 능력이 있다.

4. 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.

HelloService 인터페이스의 of메서드는 매개변수에 따라 다른 클래스 타입을 리턴할 수 있다.

 

public interface HelloService {

    public String hello();

    static HelloService of(String lang){
        if(lang.equals("ko")){
            return new KoreanHelloService();
        }else{
            return new EnglishHelloService();
        }
    }
}

 

public class EnglishHelloService implements HelloService{

    @Override
    public String hello(){
        return "hello";
    }
}

 

public class KoreanHelloService implements HelloService{

    @Override
    public String hello(){
        return "안녕";
    }
}

 

public class HelloServiceFactory {

    public static void main(String[] args) {
        System.out.println(HelloService.of("ko").hello());
        System.out.println(HelloService.of("h").hello());
    }
}

 

단점

 

1. 생성자를 만들지 않고 정적 팩터리 메서드만 제공하면 상속이 불가능한 클래스가 된다.

2. 정적 팩터리 메서드는 프로그래머가 찾기 어렵다.