데이터를 업데이트할 때 변경이 실제로 필요한지 여부를 판단하는 메커니즘이 필요한데, 객체의 이전 상태와 새 상태를 비교하여 변화가 있었는지 확인하는 것이 바로 객체의 변경 감지이다
isUpdated
라는 flag값을 사용했었는데, 코드가 길어지고, 한 눈에 들어오지 않아, 변경 감지 로직을 추가하여 리팩토링 하였다 그 과정을 기록하고자 한다 😆😆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())
);
}
}
equals
메서드를 사용하여 비교를 하게 되면 값과 scale(소숫점 이하 자리수)을 모두 비교하기 때문에 원하는 비교를 할 수 없기에 compareTo()
메서드를 사용하여 값만 비교해야 한다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"
);
}
}