정적 팩토리 메서드란 객체 생성의 역할을 하는 클래스 메서드라고 의미를 요약할 수 있다.
클라이언트가 클래스의 인스턴스를 얻는 전통적인 수단은 public 생성자를 이용하는 것이지만
정적 팩터리 메서드로도 제공할 수 있다.
다음은 java.time 패키지에 포함된 LocalTime 클래스의 정적 팩토리 메서드이다.
// LocalTime.class
...
public static LocalTime of(int hour, int minute) {
ChronoField.HOUR_OF_DAY.checkValidValue((long)hour);
if (minute == 0) {
return HOURS[hour];
} else {
ChronoField.MINUTE_OF_HOUR.checkValidValue((long)minute);
return new LocalTime(hour, minute, 0, 0);
}
}
...
// hour, minutes을 인자로 받아서 9시 30분을 의미하는 LocalTime 객체를 반환한다.
LocalTime openTime = LocalTime.of(9, 30);
of 메서드처럼 직접적으로 생성자를 통해 객체를 생성하는 것이 아닌 메서드를 통해서 객체를 생성하는 것을 정적 팩토리 메서드라고 한다. 같은 예시로 enum클래스의 valueof() 메서드가 있다.
정적 팩터리 메소드의 장점을 알아보자.
첫번째, 이름을 가질 수 있다.
생성자에 넘기는 매개변수와 생성자 자체만으로는 반환될 객체의 특성을 제대로 설명하지 못하지만
정적 팩터리 메서드는 이름만 잘 지으면 반환될 객체의 특성을 쉽게 묘사할 수 있다.
하나의 시그니처로는 생성자를 하나만 만들 수 있다. 매개변수들의 순서를 다르게 한 생성자를 추가하는 식으로 이 방법을 피해볼 수 있지만 추천하지는 않는다.
정적 팩토리 메서드에는 이러한 제약이 없다. 한 클래스에 시그니처가 같은 생성자가 여러개 필요하다면 생성자를 정적 팩터리 메서드로 바꾸고 각각의 차이를 들어내는 이름으로 변경하는 것을 추천한다.
두번째, 호출될 때마다 인스턴스를 새로 생성하지 않아도 된다.
불변클래스는 인스턴스를 미리 만들어 놓거나 새로 생성한 인스턴스를 캐싱하여 재활용하는 식으로 불필요한 객체 생성을 피할 수 있다.
반복되는 요청에 같은 객체를 반환하는 식으로 정적 팩터리 방식의 크래스는 언제 어느 인스턴스를 살아 있게 할 지 통제할 수 있다. 인스턴스를 통제하면 클래스를 싱글턴으로 만들 수 있고 인스턴스화 불가로 만들 수도 있다.
세번째, 반환 타입의 하위 타입 객체를 반환할 수 있다.
이건 자바의 다형성 특징을 이용한 내용이다.
인터페이스 자체를 반환할 수 있어서 하위 클래스를 노출시키지 않고도 반환할 수 있다.
class Main{
public static Human createPerson(String code){
if(madeMan(code)){
return Man("남자");
} else{
return Woman("여자");
}
}
}
//대략 이런식
java.util.Collections는 핵심 인터페이스들에 수정 불가나 동기화 등의 기능을 덧붙인 총 45개의 유틸리티 구현체를 제공하는데 이 구현체의 대부분을 정적 팩토리 메서드를 통해 얻도록 했다.
네번째, 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.(캡슐화)
반환 타입의 하위타입이기만하다면 어떤 클래스의 객체를 반환하던 상관이 없다.
클라이언트는 팩터리가 건네주는 객체가 어느 클래스의 인스턴스인지 알 수 없고 알 필요도 없다.
정적 팩토리 메서드를 사용한다면 내부 구현을 캡슐화할 수 있다.
캡슐화(Encapsulization)란?
데이터의 은닉을 말한다. 여기서는 생성자를 클래스의 메서드 안으로 숨기면서 내부 상태를 외부에 드러낼 필요없이 객체 생성 인터페이스 단순화 시킬 수 있다.
또한 의존성을 낮춰서 유지보수적인 부분에서도 좋다.
단점
상속을 하려면 public이나 protected 생성자가 필요한데, 정적 팩토리 메서드만 제공하면 하위 클래스를 만들 수 없다는 단점이 있다. 컬렉션 프레임워크의 유틸리티 구현 클래스들은 상속할 수 없다는 얘기이다. (Collections 클래스의 생성자 접근제어자는 private이다.)
또한 개발자들이 찾기 어렵다는 점이다. 생성자처럼 API설명에 명확히 드러나지 않아 사용자가 정적 팩토리 메서드 방식 클래스를 인스턴스화할 방법을 찾아야한다.
https://tecoble.techcourse.co.kr/post/2020-05-26-static-factory-method/
'언어 > JAVA' 카테고리의 다른 글
SingleTon Pattern (0) | 2022.02.15 |
---|---|
정적 멤버 클래스 vs 비정적 멤버 클래스 (0) | 2022.02.07 |
strategy pattern (0) | 2022.01.22 |
Adapter Pattern (0) | 2022.01.21 |
[UML]클래스 다이어그램 (0) | 2022.01.19 |