반드시X ! 고려하라 !
먼저 생성자란?
Order(){}
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 static
언제 사용하냐?
Order(주문)을 관리하는데, 긴급주문도 생성자에 추가하고 싶다면?
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 class Order {
private boolean prime ;
private boolean urgent ;
private Product product ;
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 ;
}
}
public class Settings {
private boolean useAutoSteering;
private boolean userABS;
private Settings() {}
public static void main(String[] args){
System.out.println(new Settings());
System.out.println(new Settings());
System.out.println(new Settings());
}
}
위 코드 실행 시, 아래와 같이 인스턴스를 각자 생성.
정적 팩토리 메소드는 !?
-> 객체의 생성은 내가 담당하겠어 ! 란 의미
public class Settings {
private boolean useAutoSteering;
private boolean userABS;
private Settings() {}
private static final Settings SETTINGS = new Settings();
public static Settings newInstance() { // 생성해둔 객체를 전달
return SETTINGS;
}
public static void main(String[] args){
Settings settings1 = Settings.newInstance();
Settings settings2 = Settings.newInstance();
System.out.println(settings1);
System.out.println(settings2);
}
}
위 코드 실행 시, 똑같은 인스턴스 사용
public interface HelloService {
String hello();
static String hi() {
prepareMessage();
return "hi";
}
static private void prepareMessage() {
}
static String hi1() {
prepareMessage();
return "hi";
}
static String hi2() {
prepareMessage();
return "hi";
}
default String bye() {
return "bye";
}
}
public class HelloServiceFactory {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
ServiceLoader<HelloService> loader = ServiceLoader.load(HelloService.class);
Optional<HelloService> helloServiceOptional = loader.findFirst();
helloServiceOptional.ifPresent(h -> {
System.out.println(h.hello());
});
HelloService helloService = new ChineseHelloService();
System.out.println(helloService.hello());
// Class<?> aClass = Class.forName("me.whiteship.hello.ChineseHelloService");
// Constructor<?> constructor = aClass.getConstructor();
// HelloService helloService = (HelloService) constructor.newInstance();
// System.out.println(helloService.hello());
}
}
정적 팩터리 메서드와 public 생성자는 각자의 쓰임새가 있으니 상대적인 장단점을 이해하고 사용하는 것이 좋다. 그래도 정적 팩토리를 사용하는 게 유리한 경우가 더 많으므로 무작정 public 생성자를 쓰지는 말자.
이펙티브 자바 책, 인프런 백기선님 강의