인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

gusdn85554님의 프로필 이미지
gusdn85554

작성한 질문수

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

주문 도메인 개발 단원 질문

작성

·

221

0

영한님, 서포터즈님들 안녕하세요 항상 질문에 대한 답변 감사드립니다.

주문 도메인 개발 섹션을 공부하는 중에 궁금한 점이 생겨 질문드립니다.

저는 orderPrice 라는 필드를 왜 따로 만드신지 궁금합니다.

item 객체가 존재하는데, 왜 orderPrice 라는 값을 따로 주셨을까? 분명히 이유가 있으실텐데 라는 생각으로 답을 찾으려 했지만, 찾지 못해 질문드립니다!

 
---------------------------------------------

주문 취소 부분입니다.

처음에는 cancel만으로 어떻게 주문이 취소되지 라는 생각으로 QnA들을 모두 찾아보았습니다. 

더티 체킹으로 인하여 persist 를 하지 않아도 주문 취소가 된다고 이해됐습니다.

하지만 주문 취소는 해당 주문이 삭제되는 것으로 수량 뿐만 아니라 order의 객체가 repository에서 지워져야 하는거아닌가요?

현재 상태는 repository에 객체는 존재하고, 재고 수량만 복원이 된 것이 아닌가 생각이 듭니다!

혹시나 뒷부분에서 강의해주신다면 죄송합니다,,

 

----------------------------------

setXXX 사용에 관해 궁금한 점이 생겨 QnA를 보았습니다.

영한님께서는 너무 얽매이지 마라. 사용해도 되지만 관리를 잘하면 된다 라고 말씀해주셨습니다.

혹시 위와 같은 박스 되어있는 부분이 그런 많은 상황들 중에 하나라고 생각해도 될까요?

저는 불변 객체를 만들면서 그 안에 수정할 값이 있으면 또 객체를 만들어야 하는데, 이건 너무 비효율적 아닐까?

자주 바뀌는 필드들은 setXXX를 사용해도 되지 않을까? 라는 생각입니다

답변 4

1

gusdn85554님의 프로필 이미지
gusdn85554
질문자

codesweaver님 죄송한데.. 2번의 소프트 삭제에 대해 궁금한 점이 생겼습니다,,

 

예를 들어 제가 "A" 길드를 만듭니다. 길드이름은 유니크 속성, 길드와 member가 연관관계 맺어져있는 상황입니다.

당연히 말씀하신 길드를 "하드 삭제" 하게 되면  외래키 무결성 제약조건이 위배됩니다. 

그래서 말씀하신 소프트 삭제를 하게 됩니다. 그렇다면 DB에 아직까지 길드의 이름이 남아있겠죠?

그렇다면 다시 길드를 만들 때 A라는 길드를 만들고 싶은데 DB에 현재 존재하기 때문에 만들 수 없습니다.

이 때,  길드를 삭제하면 "DUMMYGUILD" + id 로 길드이름을 바꿔서 저장하는 방법을 생각했는데 이게 옳은 방법일까요?? 이 방법을 사용하게 되면 누가 고의적으로 DUMMYGUILD을 만들고 싶다할 때 오류가 생길 것 같은데.. 해결방법이 궁금합니다 ㅠㅠ

 

또, 소프트 삭제할 경우 DB에 계속 쌓이는데 이게 문제가 없나요??

언제 한 번 싹 청소해주듯이 해줄 때가 있는건가요?

관련 검색어라도 알려주시면 감사드립니다!!

 

계속되는 꼬리 질문 죄송합니다ㅠㅠ

 

감사합니다

1

gusdn85554님의 프로필 이미지
gusdn85554
질문자

오.. 2, 3번은 확실하게 이해됐습니다.

그런데 1번에서 

"아이템은 상황에 따라 가격이 변경될 수 있기 때문입니다. 만약 어떤 사용자의 주문을 조회하는데 그때마다 상품의 가격이 달라지면 안되겠지요? 그래서 주문필드에 가격이나 상품명에 관한 정보는 별도로 추가 관리합니다" 

극단적인 예로 item이 현재 가격이 3000원입니다. 그런데 몇 시간 뒤 갑자기 3500원이 된겁니다.

이 때 고객은 분명 3000원 물품을 구매했는데 결제는 3500이 된겁니다.

orderPrice를 설정하지 않으면 현재 item.getPrice()는 3500이고,

orderPrice를 설정하면 3000원이 결제됩니다.

이런 상황을 말씀하시는건가요?

 

안녕하세요 gusdn85554 님!

.

일단 고객이 주문을 하기 위해선 item이 먼저 존재해야 합니다. 그리고 그 item의 가격을 기준으로 orderItem 이 생성되겠지요? 그러면 주문 당시의 가격을 orderItem에 보관해야 합니다. 왜냐하면 고객이 주문한 이후에도 상품의 가격이 변동될 수 있기 때문입니다. 상품의 가격이 변경된다 하더라도 고객의 주문에는 항상 '구매당시'의 금액이 조회되어야 합니다. 그래서 orderItem의 price는 '구매 당시의 금액'을 보관할 필드가 필요합니다.

.

말씀해주신 상황(상품이 3,000원인걸 분명 확인하고 결제를 하려는 순간 상품 가격이 3500원이 된 경우)도 실무에서 종종 발생하는 일입니다. 그래서 보통 최종결제 프로세스를 진행 하기전에, 장바구니에서 고객이 확인 한 결제총액(orderITem의 가격 * 수량 을 모두 더한 값 + 배송비 - 포인트)이 현재도 유효한 값인지 다시 확인합니다. 그래서 두 값이 불일치하면 주문 진행을 멈추고 고객을 장바구니로 돌려보내느 등의 절차를 넣습니다.

gusdn85554님의 프로필 이미지
gusdn85554
질문자

오.. 극단적인 예인 줄 알았는데 실무에서도 종종 발생하는 일이라니 너무 신기합니다..

이런 변수 하나로 위와 같은 상황을 없앨 수 있는 점이 너무 재밌네요

좋은 지식 얻어가네요 감사합니다 codesweaver님!!

1

안녕하세요, gusdn85554 님. 공식 서포터즈 codesweaver 입니다.


1. 아이템에 orderItem에 또 가격이 존재하는 이유는, 아이템은 상황에 따라 가격이 변경될 수 있기 때문입니다. 만약 어떤 사용자의 주문을 조회하는데 그때마다 상품의 가격이 달라지면 안되겠지요? 그래서 주문필드에 가격이나 상품명에 관한 정보는 별도로 추가 관리합니다. 그래서 아이템이 아예 삭제 된 경우에도 고객의 주문을 조회할 수 있도록 합니다.

 

2. 주문을 삭제하지 않고 상태만 변경하는 이유도 후에 관리상의 목적입니다. 삭제에는 '하드 삭제' 와 '소프트 삭제'라는 개념이 있는데 하드 삭제는 말그대로 데이터베이스에서 지워버리는 것이고, 소프트 삭제란 isDeleteYn 같은 필드의 값을 Y, N으로 업데이트 해서 주문이 삭제된 상태임을 나타내는 방법입니다. 대부분의 데이터는 소프트 삭제를 많이 합니다. 하드 삭제를 할 경우 연관된 테이블의 무결성이 깨질 수 있기 때문입니다. 

 

3. setXxx() 를 사용하지 말라는 말을 자세히 풀면... 개발을 하다보면 습관적으로 getter/setter를 추가하는 경우가 많습니다. 정말 setter가 필요한지 아닌지 판단하기도 전에 습관적으로 추가하는 것이죠. 그래서 이런 부분을 지양하라는 것입니다. setter가 많아질수록 디버그가 어려워질 수 있고 캡슐화, 추상화가 제대로 되었다고 보기 힘들기 때문입니다. 그러나 정말 자주 변경할 필요가 있다면 그런 필드에 한해 추가하는것은 무관합니다.


감사합니다.

0

안녕하세요 gusdn85554 님!

.

결론부터 말씀드리면, 키로써 한 번 생성된 값은 임의로 변경하지 않는게 좋습니다. 삭제가 무결성 원칙을 깰 위험이 있듯, 변경또한 무결성 원칙을 깰 위험이 있습니다. 키가 참조되고 있는 모든 곳의 업데이트가 동시에 이루어짐을 보장할 수 있어야 하기 때문입니다. 그리고 길드 삭제 시 일정한 패턴으로 길드명을 변경하는 방법의 경우, 말씀하신 것처럼 누군가가 하필 그 패턴에 맞는 길드명을 가지고 있을 경우 문제가 발생할 수 있고, 또 한 아이디를 가진 사람이 두 번 이상 길드를 삭제하면 문제가 될 여지가 있습니다.

.

그러나 그렇다고 한번 생성된 키를 절대 지우지 못하거나 변경할 수 없다는 것은 아닙니다. 가령 회원정보의 경우 개인정보 관리법에 의해 장기 미접속자의 경우 회원테이블과 별도의 테이블로 회원정보를 보관해야 하며, 사용자에게 장기 미접속 상황임을 알려야 하는 등의 의무가 있습니다. 그리고 장기 미접속 기간이 지속되면 이를 최종적으로 삭제처리 해야 합니다. 이 처럼 정말 필요한 상황이라면 데이터를 하드 삭제하기도 합니다. 길드명을 재활용 할 필요가 강력하게 있다면, 기존 데이터를 하드 삭제하는 것도 고려해야 합니다.

.

예전에 있던 회사의 경우를 말씀드리면, 회사 창업 초창기부터 5년 이상 누적된 주문데이터 양이 방대해서 이를 old 테이블로 이전, 새로운 주문 테이블을 생성하여 최근 1년치의 주문 정보만을 옮겨놓았습니다. 1년이 지난 주문을 검색하고 싶은 경우 사용자가 검색 옵션에 추가 체크를 하도록해서 과거의 주문을 조회하도록 처리하기도 했습니다. 

.

감사합니다.

 

gusdn85554님의 프로필 이미지
gusdn85554

작성한 질문수

질문하기