객체지향에서의 양방향 참조

kdkdhoho·2023년 11월 4일
0

객체지향 설계를 할 때 양방향 참조를 하면 여러 문제가 있다고 어렴풋이 알고 있었다.
그 중에 하나로, 순환 참조 문제에 대해서만 알고 있었다.

하지만 오늘 미션을 진행하며 객체가 서로 참조하고 있다면 어떤 문제가 있는지 몸소 알게 되었다.

상황

public class Order {
    // 생략

	private List<OrderLineItem> orderLineItems;

	// 생략
}

주문 관련 엔티티인 Order가 주문에 포함되는 물품들을 가진다. (orderLineItems)

public class OrderLineItem {
	// 생략

	private Order order;

	// 생략
}

주문에 포함되는 물품 관련 엔티티인 OrderLineItemOrder를 가진다.

그리고 주문을 생성하는 서비스 로직을 작성하는 상황이다.

서비스 코드

@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에 종속된다고 할 수 있다.
OrderLineItemOrder를 참조하지 않는, 다시 말해 OrderOrderLineItem 객체를 알고 있는 형태가 자연스러울 것이다.

그럼 만약 두 객체의 생명주기가 상관이 없다면?

에어컨 객체와 리모콘 객체가 있다고 가정해보자.
이러한 상황에서는 리모콘에어컨을 알고 있는 것이 멘탈 모델과 적합해보인다.
이렇게 자연스러운 방향으로 의존 방향성이 흘러가면 되지 않을까?

그럼 만약 두 객체가 상관없다면?

현실 세계에선 떼놓을 수 없는 커피노트북을 객체 세계에서 상상해보자.
이 둘이 어떤 상호작용을 할까?

노트북이 커피를 주문할 수 있지 않을까?
커피가 노트북을 더 빠르게 움직이게 만들 수 있지 않을까?

결국, 이 또한 객체 간의 컨텍스트를 판단하는 것이 중요해보인다.

추천 자료

https://youtu.be/dJ5C4qRqAgA?si=-yGUETBYJ96dj41t

profile
newBlog == https://kdkdhoho.github.io

0개의 댓글