[Toy Project] 객체 변경 감지 로직의 구현

최지나·2023년 12월 12일
1
post-thumbnail

객체 변경 감지란?

데이터를 업데이트할 때 변경이 실제로 필요한지 여부를 판단하는 메커니즘이 필요한데, 객체의 이전 상태와 새 상태를 비교하여 변화가 있었는지 확인하는 것이 바로 객체의 변경 감지이다

  • 프로젝트를 진행하면서 product, store, category와 같은 객체들의 update 여부를 판단할 때 isUpdated라는 flag값을 사용했었는데, 코드가 길어지고, 한 눈에 들어오지 않아, 변경 감지 로직을 추가하여 리팩토링 하였다 그 과정을 기록하고자 한다 😆😆

코드

entity

public class Product {

  // field 선언 .. 
  
  public boolean isStateChanged(ProductPatch patchInput, byte[] newImgBytes) {
    return (
      !Objects.equals(name, patchInput.getName()) ||
      (
        price != null &&
        patchInput.getPrice() != null &&
        price.compareTo(patchInput.getPrice()) != 0
      ) ||
      stock != patchInput.getStock() ||
      (
        category == null
          ? patchInput.getCategoryCode() != null
          : !category.getCategoryCode().equals(patchInput.getCategoryCode())
      ) ||
      !Objects.equals(description, patchInput.getDescription()) ||
      !Arrays.equals(img, newImgBytes) ||
      !Objects.equals(barcode, patchInput.getBarcode())
    );
  }
}
  • 각 필드의 값이 변경되었는지를 확인. 하나라도 변경되었으면 true를 return
  • 여기서 BigDecimal 타입의 price 필드의 경우, equals 메서드를 사용하여 비교를 하게 되면 값과 scale(소숫점 이하 자리수)을 모두 비교하기 때문에 원하는 비교를 할 수 없기에 compareTo() 메서드를 사용하여 값만 비교해야 한다

service

public void patchProduct(String code, ProductPatch patchInput) {
    Product previousProduct = productRepository.findByProductCode(code);

    if (previousProduct == null) {
      throw new ResponseStatusException(
        HttpStatus.NOT_FOUND,
        "PRODUCT NOT FOUND"
      );
    }

    byte[] newImgBytes = null;
    if (patchInput.getImg() != null) {
      try {
        newImgBytes = patchInput.getImg().getBytes();
      } catch (IOException e) {
        throw new ResponseStatusException(
          HttpStatus.BAD_REQUEST,
          "IMAGE INPUT IS INVALID"
        );
      }
    }

    if (previousProduct.isStateChanged(patchInput, newImgBytes)) {
      if (patchInput.getName() != null) previousProduct.updateName(
        patchInput.getName()
      );
      if (patchInput.getPrice() != null) previousProduct.updatePrice(
        patchInput.getPrice()
      );
    
      // ...(생략)
      
      if (patchInput.getBarcode() != null) previousProduct.updateBarcode(
        patchInput.getBarcode()
      );

      productRepository.save(previousProduct);
    } else {
      throw new ResponseStatusException(
        HttpStatus.NO_CONTENT,
        "PRODUCT IS NOT UPDATED"
      );
    }
  }

변경 감지 로직의 중요성

  • 성능 최적화: 불필요한 데이터베이스 작업을 줄여 성능을 향상
  • 데이터 무결성: 실제로 변경이 필요한 경우에만 업데이트를 수행하여 데이터의 정확성을 보장
  • 유지보수성: 코드의 가독성과 유지보수성이 향상
profile
의견 나누는 것을 좋아합니다 ლ(・ヮ・ლ)

0개의 댓글