= 상위 Service Layer의 도입(Assemble Layer) =

<aside> 💡 Assemble Layer 도입 원칙

</aside>


@RequiredArgsConstructor
@Service
public class PurchaseOrderAssembleServiceImpl implements PurchaseOrderService {

	// * 하위 레이어 DI 수행 *
	private final UserReadService userReadService; 
	private final StoreReadService storeService;

	@Transactional
	@Override
	public Long createPurchaseOrder(CreatePurchaseOrderRequestDto createPurchaseOrderRequestDto, AuthUser user) {
		UserEntity userEntity = userReadService.getUser(1L);
		Store store = storeService.getStore(1L);
		
		return 1L;
	}
}
@RequiredArgsConstructor
@Service
public class ProductServiceImpl implements ProductService {
	
	private final ProductRepository productRepository;

	// * 하위 레이어간 의존 허용 안됨 *
	private final StoreService storeService;

	@Transactional
	@Override
	public Long createProduct(CreateProductDto createProductDto) {
		// * 하위 레이어간 Communication 허용 안됨 *
		Store store = storeService.getStore(createProductDto.getRequestedStoreId());
	}
}
@RequiredArgsConstructor
@Service
public class PurchaseOrderAssembleServiceImpl implements PurchaseOrderService {
	
	// * 해당 Domain의 Repository 접근 가능 *
   private final PurchaseOrderRepository purchaseOrderRepository;
   private final UserReadService userReadService;
   private final StoreReadService storeService;

   @Transactional
   @Override
   public Long createPurchaseOrder(CreatePurchaseOrderRequestDto createPurchaseOrderRequestDto, AuthUser user) {
      ...

      PurchaseOrderEntity build = PurchaseOrderEntity.builder()
         .purchaseOrderStatus(PurchaseOrderStatus.PAID)
         .buyer(userEntity)
         .build();

      PurchaseOrderEntity newOrder = purchaseOrderRepository.save(build);
      return newOrder.getId();
   }
}
@RequiredArgsConstructor
@Service
public class PurchaseOrderAssembleServiceImpl implements PurchaseOrderService {

	private final PurchaseOrderRepository purchaseOrderRepository;
	private final UserReadService userReadService;
	private final StoreReadService storeService;

	@Transactional
	@Override
	public Long createPurchaseOrder(CreatePurchaseOrderRequestDto createPurchaseOrderRequestDto, AuthUser user) {
		UserEntity userEntity = userReadService.getUser(1L);

		// * 하위 Service Layer에서 갖고 온 Entity는 수정 불가		
		userEntity.setUserEmail("[email protected]");

		...
	}
}

@RequiredArgsConstructor
@Service
public class UserReadServiceImpl implements UserReadService {

	private final UserRepository userRepository;
	
	// * 하위 Service Layer에서 갖고 온 Entity는 수정 불가
  // * Dirty Check 방지
	@Transactional(readOnly = true)
	@Override
	public UserEntity getUser(Long userId) {
		return userRepository.findById(userId).orElseThrow(() -> {
			throw new NotFoundException("requested user id does not exist");
		});
	}
}