본문 바로가기

BE & Spring

생성 메서드(팩토리 메서드)와 생성자 접근 제한

김영한 강사님의 실전! 스프링 부트와 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로 제한하면 생성 메서드를 강제할 수 있어 구조가 더 안전해진다


let textNodes = document.querySelectorAll("div.tt_article_useless_p_margin.contents_style > *:not(figure):not(pre)"); textNodes.forEach(function(a) { a.innerHTML = a.innerHTML.replace(/`(.*?)`/g, '$1'); });