직접 참조의 문제점
- 편한 탐색 요용
- 한 애그리거트 내부에서 다른 애그리거트에 접근하여 상태를 변경할 수 있게,
- 애그리거트의 경계가 모호해지고 의존성이 증가한다.
- 성능적 고민
- JPA 사용하는 경우 지연 로딩과 즉시 로딩 중 어떤 것을 사용할지 결정해야한다.
- 애그리거트의 기능에 따라 달라짐.
- 확장성의 문제
- 시스템이 성장하면서 하위 도메인별로 분리하고,
- 다양한 저장소를 사용하게됨.
public class Order {
private Orderer orderer;
public void changeShippingInfo(ShippingInfo newShippingInfo, boolean useNewShippingAddrAsMemberAddr) {
if (useNewShippingAddrAsMemberAddr) {
orderer.getMember().changeAddress(newShippingInfo.getAddress()); // 직접 참조
}
}
}
public class Orderer {
private Member member;
private String name;
}
public class Member {
// Member details
}
ID를 이용한 간접 참조
- ID 참조의 장점
- 애그리거트의 경계를 명확히 하고, 애그리거트 간의 물리적 연결 제거
- 모델의 복잡도 DOWN , 응집도 UP
- 구현 복잡도의 감소
- 다른 애그리거트를 직접 참조 X
- 로딩 전략에 대한 고민이 필요가 없어짐
- 필요한 애그리거트는 응용 서비스에서 ID로 로딩’
- 코드
public class Order { private Orderer orderer; } public class Orderer { private MemberId memberId; private String name; } public class Member { private MemberId id; } public class ChangeOrderService { @Transactional public void changeShippingInfo(OrderId id, ShippingInfo newShippingInfo, boolean useNewShippingAddrAsMemberAddr) { Order order = orderRepository.findById(id); if (order == null) throw new OrderNotFoundException(); order.changeShippingInfo(newShippingInfo); if (useNewShippingAddrAsMemberAddr) { //order 에서 ID 값을 가져와서 간접 참조 Member member = memberRepository.findById(order.getOrderer().getMemberId()); member.changeAddress(newShippingInfo.getAddress()); } } }
조회 성능과 N+1 문제의 발생
- N+1 조회 문제
- ID를 이용한 참조는
지연 로딩과
유사한 효과를 가지지만
- N+1 조회 문제로 인해 전체 조회 속도가 느려질 수 있다.
- ID를 이용한 참조는
- 조회 전용 쿼리 사용
- 조회 성능을 향상시키기 위해 조회 전용 쿼리를 사용하며, JPA의 JPQL이나 마이바티스와 같은 기술을 이용해 구현할 수 있다.
- JPQL사용 코드 예시
@Repository public class JpaOrderViewDao implements OrderViewDao { @PersistenceContext private EntityManager em; @Override public List<OrderView> selectByOrderer(String ordererId) { String selectQuery = "select new com.myshop.order.application.dto.OrderView(o, m, p) " + "from Order o join o.orderLines ol, Member m, Product p " + "where o.orderer.memberId.id = :ordererId " + "and o.orderer.memberId = m.id " + "and index(ol) = 0 " + "and ol.productId = p.id " + "order by o.number.number desc"; TypedQuery<OrderView> query = em.createQuery(selectQuery, OrderView.class); query.setParameter("ordererId", ordererId); return query.getResultList(); } }
Uploaded by N2T
'도메인주도개발' 카테고리의 다른 글
Image 생성 관련 최적화 (0) | 2024.01.05 |
---|---|
애그리거트? (0) | 2024.01.02 |
애그리거트를 팩토리를 사용하기 (0) | 2024.01.02 |
도메인 전문가와 개발자 간 지식 공유 (0) | 2023.12.30 |
도메인 모델 (0) | 2023.12.30 |