김영한 강사님의 실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발 강의를 참고했습니다
왜 객체 생성 방식을 고민해야 할까?
단순한 엔티티라면 생성자나 setter만으로도 충분할 수 있다
하지만 연관관계가 복잡한 도메인 객체에서는 얘기가 다르다
ex) 주문(Order) 객체 생성
// 주문 생성 예시
Order order = new Order();
order.setMember(member);
order.setDelivery(delivery);
order.addOrderItem(orderItem1);
order.addOrderItem(orderItem2);
order.setStatus(OrderStatus.ORDER);
order.setOrderDate(LocalDateTime.now());
이 방식은 다음과 같은 문제가 있다
- 실수로 setStatus()를 빠뜨릴 수도 있고
- addOrderItem()을 누락할 수도 있고
- Order 객체가 완전하지 않은 상태로 생성될 위험이 있다
복잡한 객체는 생성 메서드를 활용하자
이런 문제를 해결하기 위해 강의에서는 정적 팩토리 메서드(생성 메서드)를 사용을 권장한다
public static Order createOrder(Member member, Delivery delivery, OrderItem... orderItems) {
Order order = new Order();
order.setMember(member);
order.setDelivery(delivery);
for (OrderItem orderItem : orderItems) {
order.addOrderItem(orderItem);
}
order.setStatus(OrderStatus.ORDER);
order.setOrderDate(LocalDateTime.now());
return order;
}
✅ 생성 메서드의 장점
- 객체 생성과 초기화 과정을 한 곳에 모을 수 있다
- 연관관계를 포함한 필수 설정을 누락 없이 처리할 수 있다
- 생성 로직이 추후 변경될 경우, 이 메서드만 고치면 되므로 유지보수가 쉬워진다
생성 메서드를 제대로 쓰려면, 생성자 접근도 제한하자
하지만 생성 메서드를 만들어놓고도 여전히 new Order( )로 객체를 직접 생성한다면?
의도하지 않은 불완전한 객체가 만들어질 수 있다
이를 방지하려면 기본 생성자에 접근 제한을 두는 것이 좋다
JPA는 프록시 객체 생성을 위해 기본 생성자가 반드시 필요하다
외부에서 이를 호출하지 못하도록 접근 제어자를 protected로 설정하면 된다
public class Order {
protected Order();
...
}
// 롬복 활용 시
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Order {}
이렇게 하면 외부에서는 직접 생성할 수 없고, 반드시 createOrder( ) 같은 생성 메서드를 통해서만 객체를 만들 수 있게 된다
정리
- 연관관계가 복잡한 도메인에서는 객체 생성 시 실수나 누락이 발생하기 쉽다
- 생성 메서드는 이러한 위험을 줄이고, 객체 생성을 안정적으로 통제할 수 있는 방법이다
- 생성자를 protected로 제한하면 생성 메서드를 강제할 수 있어 구조가 더 안전해진다
'BE & Spring' 카테고리의 다른 글
Spring에서 Bean 등록하는 2가지 방법 (2) | 2025.03.03 |
---|---|
[Java] 프로그래머스 - 가장 큰 수 (정렬) (0) | 2025.02.12 |
[COTATO] 백엔드 네트워킹 - Gilded Rose 코드 리팩토링 (0) | 2024.10.30 |
스프링 MVC에서 주로 사용하는 어노테이션 (0) | 2024.01.07 |