
예를 들면
이렇게 서로 연관된 상황에서 다른 Domain의 Entity 정보가 필요한 경우 3가지의 방식으로 구현 가능

Domain 간의 경계 설정
Service Layer를 경계로 채택
<aside> 💡 다른 경계에서의 단점
Service Layer를 통한 통신의 장점
Service Layer를 통해 통신함으로써 Domain간의 서비스 비즈니스 로직은 침범하지 않음
각 Domain의 Resource와는 결합이 낮아짐
추후 코드의 확장이 필요한 경우 다른 Domain과 통신하는 Service Layer만 분리하여 사용 가능

Service Layer간 Communication 시 문제점
이전 섹션에 다뤘듯이 Service Layer 간 Communication을 통해 Domain간의 Loose Coupling과 High Cohesion 을 달성하려고 했음
@RequiredArgsConstructor
@Service
public class AServiceImpl implements AService {
private final ARepository aRepository;
private final XService xService;
@Override
public void createA(A a) {
xService.createA(a);
aRepository.save(a);
}
@Override
public List<ADto> findAllA() {
return aRepository.findAll();
}
}
@RequiredArgsConstructor
@Service
public class XServiceImpl implements XService {
private final XRepository xRepository;
private final AService aService;
@Override
public void createX(A a) {
List<ADto> aList = aService.findAll();
}
}
서로 참조하고 있는 형태
<aside> 💡 문제점
다시 이전 Domain 간의 경계를 지정하는 문제
@RequiredArgsConstructor
@RestController
public OrderController {
private final UserService userService;
private final ProductService productService;
private final OrderService orderService;
@PostMapping("api/orders/")
public Long createOrder(OrderDto orderDto) {
UserEntity buyer = UserService.getUser(orderDto.getUserId());
ProductEntity product = ProductService.getProduct(orderDto.getProductId());
OrderEntity order = orderSerivce.createOrder(buyer, product, orderDto.getPurchaseAmount());
return order.getId();
}
}
<aside> 👉 OrderController가 다른 Domain의 Service를 직접적으로 호출할 수 있음
</aside>
<aside> 👉 Entity가 Controller Layer에 노출되는 문제 발생 (Entity의 변경이 Controller Layer의 변경으로 이어질 수 있음)
</aside>
<aside> 👉 Controller Layer에서 비즈니스 로직이 노출됨
</aside>
<aside> 👉 Transaction과 함께 생각하면 Controller는 Interface를 기반으로 생성하지 않는다면 Controller layer에서 Class Proxy Mode를 통해 Transaction을 수행할 수 있지만 MVC의 경계가 무너지는 문제 발생
</aside>
@RequiredArgsConstructor
@Service
public OrderService {
private final UserRepository userRepository;
private final ProductRepository productRepository;
private final OrderRepository orderRepository;
@Transactional
public Long createOrder(OrderDto orderDto) {
UserEntity buyer = userRepository.findById(orderDto.getUserId());
ProductEntity product = productRepository.findById(orderDto.getProductId());
OrderEntity order = new OrderEntity(buyer, product, orderDto.getPurchaseAmount());
// buyer.setUserEmail("[email protected]"); Dirty Checking
orderRepository.save(order);
return order.getId();
}
}
<aside> 👉 이전과 다르게 MVC의 경계가 무너지지는 않음
</aside>
<aside> 👉 하지만 다른 Domain의 Repository를 사용할 경우 Domain간의 경계가 없어짐
</aside>
readOnly = true를 통해서 다른 Domain의 Entity들은 수정 불가능하게 만들 의도
