팩토리 메소드
팩토리(Factory)는 '공장'이라는 뜻을 가지고 있습니다. 일반적으로 클래스의 객체를 생성할 때, 생성자를 통해서 객체를 생성하지만 팩토리 메소드 라는 공장을 통해서 객체를 만들 수도 있습니다.
public class User{
private String username;
public Person(String username){
this.username = username;
}
}
위에 코드는 Java로 객체를 작성할 때, 많이 사용하던 코드입니다.
User user = new User("유저 이름");
그리고 우리는 객체를 생성할 때, 위와 같이 생성자 호출을 통해서 객체를 생성했습니다. 그런데 우리는 생성자의 인자만 봐서는 이것이 유저 이름을 나타내는 것인지, 다른 것을 나타내는 것인지 클래스를 뜯어보지 않고서는 도무지 알 길이 없습니다.
하지만 팩토리 메소드로 구현을 하면 다음과 같습니다.
public class User{
private String username;
private User(String username){
this.username = username;
}
public static User ofUsername(String username){
return new User(username);
}
}
// 호출시
User user = User.ofUsername("유저 이름");
위 코드를 보고 여러분은 인자 값이 '유저 이름' 라는 것을 쉽게 추측할 수 있습니다. 또한 생성자를 private 으로 변경해서 팩토리 메서드를 통한 객체 생성을 강제하는데 이 것이 팩토리 메서드의 장점입니다.
🏷️ 장점
✅ 객체 목적을 명확하게 합니다.
위에서 설명한 것처럼 떠한 목적으로 만들어진 것인지 new만 봐서는 쉽게 판단할 수 없는 것을 static method를 통해서, 이름을 가지게 할 수 있습니다.
from 과 of 같은 정적 팩토리 메서드 네이밍 규칙을 따를수도 있고, from과 of 대신 적절한 이름을 갖는 메소드 명을 통해서 보다 객체 생성과 사용의 목적을 명확히 할 수 있다는 장점이 있습니다.
✅ 객체 생성의 캡슐화.
팩토리 메서드를 통해서 하나의 value 나 dto, 또는 entity를 매개변수로 정해서 객체 생성에 필요한 매개변수를 캡슐화를 해줄 수 있다는 장점이 있습니다.
본래 dto 객체를 반환해줄때에, 매개변수로 받은 객체에서 일일이 getter 메소드를 통해서 매개변수에 집어 넣어주고, 새로운 dto객체를 생성해줘야 했지만, 정적 팩토리 메서드를 사용하면 dto 내부 구조를 모르더라도 dto 객체 생성이 쉽게 가능하게 합니다.
✅ 하위 타입 반환이 가능합니다.
A라는 클래스를 B, C, D 가 상속 받는 경우일 때, A의 정적 팩토리 메서드를 통해서 B, C, D 의 객체를 생성하여 반환할 수 있습니다.
상속과 다형성의 특징 덕분에 가능하기도 하지만, new와 생성자와는 달리, 정적 팩토리 메서드가 객체라는 리턴 타입을 갖는다는 특징이 더해져서 하위 타입으로 리턴을 해줄 수 있다는 장점을 가지게 됩니다.
✅ 여러번 사용 시 새로운 객체를 생성할 필요가 없습니다.
생성자를 private로 설정하여 다른 외부의 접근을 막아두고, 이후 팩토리 메서드를 통해서 정해진 객체만을 사용하도록 구현하는게 가능합니다. 또한 이를 통해서 불필요한 다른 객체 생성을 막을 수 있습니다.
🏷️ 단점
✔️ 정적 팩토리 메서드를 사용할 때, 생성자를 private를 통해서 사용하는 경우 상속을 통한 확장이 불가능해집니다. 상속을 통한 확장을 막는 것은 상황에 따라 장점이자 단점이 될 수 있을 것 같습니다.
✔️ 생성자는 코드의 윗부분에 위치하는 경우가 많아 찾기가 용이하지만, 정적 팩토리 메서드의 경우에는 위치가 정해지지 않아 또 다른 개발자가 사용 시에 찾아야 하는 경우가 발생할 수 있습니다.
🏷️ 정적 팩토리 메서드 네이밍 규칙
- from : 하나의 매개 변수를 받아서 객체를 생성
- of : 여러개의 매개 변수를 받아서 객체를 생성
- valueOf : from 과 of 보다 자세하게 사용
- getInstance | instance : 인스턴스를 생성. 이전에 반환했던 것과 같을 수 있음.
- newInstance | create : 새로운 인스턴스를 생성
- get[OtherType] : 다른 타입의 인스턴스를 생성. 이전에 반환했던 것과 같을 수 있음.
- new[OtherType] : 다른 타입의 새로운 인스턴스를 생성.
📖 Reference
'코딩 공부 > web & Java' 카테고리의 다른 글
[Java / TDD] 테스트 케이스 작성시 발생한 영속성 관련 오류 (0) | 2024.08.28 |
---|---|
[JWT] JWT 0.12.5 최신화 문제 해결 (0) | 2024.07.20 |
[JPA] N + 1 문제 (0) | 2024.04.23 |
[Spring] Proxy (0) | 2024.04.17 |
[Java] DTO를 Record로 만드는 이유 (0) | 2024.04.17 |