정적 펙토리 메서드(static factory method)란?
정적 펙토리 메서드에서 펙토리란 객체를 생성하는 역할을 이야기 합니다. 즉 객체를 생성하는 static method라고 생각하면 편합니다.
정적 팩토리 메서드의 장점(생성자와 비교하여)
- 이름을 갖는다.
public class User {
private String name;
public User(String name) {
this.name = name;
}
public static User nameOf(String name) {
return new User(name);
}
public static void main(String[] args) {
User user1 = new User("홍길동");
User user2 = User.nameOf("홍길동");
}
}
단순히 new User("홍길동")
으로 객체를 생성하는 것 보다 User.nameOf("홍길동")
으로 홍길동이란 이름의 User를 생성한다는 것을 보다 명확하게 표현할 수 있습니다.
- 호출할 때마다 새로운 객체를 생성할 필요가 없다.
public class State {
private static Map<String, State> stateNames = new HashMap<>();
static {
stateNames.put("서울", new State("서울"));
stateNames.put("인천", new State("인천"));
stateNames.put("대전", new State("대전"));
stateNames.put("대구", new State("대구"));
stateNames.put("부산", new State("부산"));
stateNames.put("광주", new State("광주"));
}
private String stateName;
private State(String stateName) {
this.stateName = stateName;
}
public static State from(String stateName) {
State state = stateNames.get(stateName);
if (state == null) {
throw new IllegalArgumentException("거기가 어딘가요?");
}
return state;
}
@Override
public String toString() {
return "여기는 " + stateName + "입니다.";
}
public static void main(String[] args) {
State seoul = State.from("서울");
System.out.println(seoul);
State invalidState = State.from("충청남도");
}
}
- 하위 자료형 객체를 반환한다.
public class Soap {
public static Soap createSoap(int price) {
if (price < 10000) return new IndustrialSoap();
return new HandmadeSoap();
}
public static void main(String[] args) {
Soap soap = Soap.createSoap(1000);
System.out.println("soap instanceof Soap Is " + (soap instanceof Soap));
System.out.println("soap instanceof HandmadeSoap IS " + (soap instanceof HandmadeSoap));
System.out.println("soap instanceof IndustrialSoap IS " + (soap instanceof IndustrialSoap));
}
}
class HandmadeSoap extends Soap{}
class IndustrialSoap extends Soap{}
- 입력 매개변수에 따라 다른 클래스의 객체를 반환할 수 있다.
List.of()
메서드 입니다. 매개변수가 2개까지는 List12
3개 이상부터는 ListN
을 반환하지만 사용하는 입장에서는 무엇을 반환하던 상관하지 않고 사용합니다. 또한 장점 3번의 예제도 가격에 따라 핸드메이드비누 또는 공산품비누를 리턴하므로 장점4번을 설명해주고 있습니다.
- 객체 생성을 캡슐화
@Getter
public class User {
private Long id;
private String name;
private int age;
}
public class UserDto {
private String name;
private int age;
public UserDto(String name, int age) {
this.name = name;
this.age = age;
}
public static UserDto from(User user) {
return new UserDto(user.getName(), user.getAge());
}
}
UserDto userDto1 = new UserDto(user.getName(), user.getAge());
UserDto userDto2 = UserDto.from(user);
이렇듯 정적 팩토리 메서드는 가독성을 향상시켜주고 좀 더 객체지향적으로 프로그래밍 할 수 있도록 도와줍니다.
정적 펙토리 메서드의 단점
- 상속을 하려면 public이나 protected 생성자가 필요하므로 정적 펙토리 메서드만 있는 경우 하위 클래스를 만들 수 없다.
- 정적 펙토리 메서드는 찾기가 어렵다. => 네이밍 컨벤션을 통해 확인
정적 펙토리 메서드 네이밍 컨벤션
- from: 하나의 매개변수를 받아서 같은 타입의 인스턴스를 반환(형변환)
- of: 여러개의 매개변수를 받아서 적합한 타입의 인스턴스를 반환(집계)
- valueOf:
from
과of
의 자세한 버전 - getInstance 또는 instance: 인스턴스를 반환, 같은 인스턴스임을 보장하지 않음
- newInstance 또는 create: 인스턴스를 반환, 새로운 인스턴스임을 보장
- getType: getInstance와 같으나, 다른 클래스의 인스턴스를 반환 "Type"은 반환할 객체의 타입
- newType: newInstance와 같으나, 다른 클래스의 인스턴스를 반환 "Type"은 반환할 객체의 타입
- type:
getType
과newType
의 간결한 버전
반응형
'스터디 > 이펙티브 자바' 카테고리의 다른 글
[Effective Java] Item 6. 불필요한 객체 생성을 피하라 (0) | 2022.05.15 |
---|---|
[Effective Java] Item 5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용 (0) | 2022.05.14 |
[Effective Java] Item 4. 인스턴스화를 막으려면 private 생성자를 사용 (0) | 2022.05.14 |
[Effective Java] Item 3. private 생성자나 Enum타입으로 싱글턴임을 보증하라 (3) | 2022.05.13 |
[Effective Java] Item 2. 생성자에 매개변수가 많다면 빌더 (0) | 2022.05.11 |