객체지향 설계를 할 때 양방향 참조를 하면 여러 문제가 있다고 어렴풋이 알고 있었다.
그 중에 하나로, 순환 참조 문제에 대해서만 알고 있었다.
하지만 오늘 미션을 진행하며 객체가 서로 참조하고 있다면 어떤 문제가 있는지 몸소 알게 되었다.
public class Order {
// 생략
private List<OrderLineItem> orderLineItems;
// 생략
}
주문 관련 엔티티인 Order
가 주문에 포함되는 물품들을 가진다. (orderLineItems
)
public class OrderLineItem {
// 생략
private Order order;
// 생략
}
주문에 포함되는 물품 관련 엔티티인 OrderLineItem
이 Order
를 가진다.
그리고 주문을 생성하는 서비스 로직을 작성하는 상황이다.
@Transactional
public Order create(OrderCreateRequest request) {
OrderTable orderTable = orderTableRepository.getById(request.orderTableId());
Order order = new Order(orderTable, OrderStatus.COOKING, LocalDateTime.now(), orderLineItems); // orderLineItems가 선언되지 않았다.
List<OrderLineItem> orderLineItems = new ArrayList<>();
for (CreateOrderLineItemRequest orderLineItemRequest : request.createOrderLineItemRequests()) {
Menu menu = jpaMenuRepository.getById(orderLineItemRequest.menuId());
OrderLineItem orderLineItem = new OrderLineItem(order, menu, orderLineItemRequest.quantity());
orderLineItemRepository.save(orderLineItem);
}
return orderRepository.save(order);
}
@Transactional
public Order create(OrderCreateRequest request) {
OrderTable orderTable = orderTableRepository.getById(request.orderTableId());
List<OrderLineItem> orderLineItems = new ArrayList<>();
for (CreateOrderLineItemRequest orderLineItemRequest : request.createOrderLineItemRequests()) {
Menu menu = jpaMenuRepository.getById(orderLineItemRequest.menuId());
OrderLineItem orderLineItem = new OrderLineItem(order, menu, orderLineItemRequest.quantity()); // order가 선언되지 않았다.
orderLineItemRepository.save(orderLineItem);
}
Order order = new Order(orderTable, OrderStatus.COOKING, LocalDateTime.now(), orderLineItems);
return orderRepository.save(order);
}
위 두 코드에서 보다시피, 어느 한 객체를 생성하면 다른 객체는 아직 생성되지 않는 문제가 있다.
가장 좋은 해결책은 양방향 의존관계를, 단방향으로 푸는 것이다.
그럼 방향성을 어떻게 설정할 것인가에 대한 문제가 생긴다.
이는 두 객체의 컨텍스트를 잘 보고 판단해야 될 것 같다.
지금 같은 상황에선 OrderLineItem
의 생명주기는 Order
에 종속된다고 할 수 있다.
OrderLineItem
이 Order
를 참조하지 않는, 다시 말해 Order
가 OrderLineItem
객체를 알고 있는 형태가 자연스러울 것이다.
에어컨
객체와 리모콘
객체가 있다고 가정해보자.
이러한 상황에서는 리모콘
이 에어컨
을 알고 있는 것이 멘탈 모델과 적합해보인다.
이렇게 자연스러운 방향으로 의존 방향성이 흘러가면 되지 않을까?
현실 세계에선 떼놓을 수 없는 커피
와 노트북
을 객체 세계에서 상상해보자.
이 둘이 어떤 상호작용을 할까?
노트북이 커피를 주문할 수 있지 않을까?
커피가 노트북을 더 빠르게 움직이게 만들 수 있지 않을까?
결국, 이 또한 객체 간의 컨텍스트를 판단하는 것이 중요해보인다.