기존 인스턴스를 변경하는 대신, 새로운 인스턴스를 생성하여 반환하는 방식을 활용할 수 있다.
Member 엔티티를 생성(Create)할 때뿐만 아니라, 수정(Update)과 삭제(Delete) 시에도 새로운 인스턴스를 생성하여 리턴하는 패턴을 적용할 수 있다.@Getter
@AllArgsConstructor
@Builder
public class Member {
private final UUID id;
private final String loginId;
private final String password;
private final MemberProfile memberProfile;
private final UUID mainCardId;
private final String paymentPassword;
private final String userKey;
private final boolean deleted;
@Builder
public Member(UUID id, String loginId, String password,
String name, LocalDate birthday, Gender gender, Role role, String email, String phone,
UUID mainCardId, String paymentPassword, String userKey, boolean deleted) {
this.id = id;
this.loginId = loginId;
this.password = password;
this.memberProfile = new MemberProfile(name, birthday, gender, role, email, phone);
this.mainCardId = mainCardId;
this.paymentPassword = paymentPassword;
this.userKey = userKey;
this.deleted = deleted;
}
public static Member create(MemberCreate memberCreate, PasswordEncoder passwordEncoder){
return Member.builder()
.loginId(memberCreate.getLoginId())
.password(passwordEncoder.encode(memberCreate.getRawPassword()))
.memberProfile(new MemberProfile(memberCreate.getName(), memberCreate.getBirthday(), memberCreate.getGender(), memberCreate.getRole(), memberCreate.getEmail(), memberCreate.getPhone()))
.mainCardId(memberCreate.getMainCardId())
.paymentPassword(passwordEncoder.encode(memberCreate.getRawPaymentPassword()))
.userKey(memberCreate.getUserKey())
.deleted(false)
.build();
}
public Member update(MemberUpdate memberUpdate, PasswordEncoder passwordEncoder){
return Member.builder()
.id(id)
.loginId(memberUpdate.getLoginId())
.password(passwordEncoder.encode(memberUpdate.getRawPassword()))
.memberProfile(new MemberProfile(memberUpdate.getName(), memberUpdate.getBirthday(), memberUpdate.getGender(), memberUpdate.getRole(), id+"@ssafy.com", memberUpdate.getPhone()))
.mainCardId(memberUpdate.getMainCardId())
.paymentPassword(passwordEncoder.encode(memberUpdate.getRawPaymentPassword()))
.userKey(memberUpdate.getUserKey())
.deleted(memberUpdate.isDeleted())
.build();
}
public Member delete(){
return Member.builder()
.id(id)
.loginId(loginId)
.password(password)
.memberProfile(memberProfile)
.mainCardId(mainCardId)
.paymentPassword(paymentPassword)
.userKey(userKey)
.deleted(true)
.build();
}
public Member updatePaymentPassword(String paymentPassword, PasswordEncoder passwordEncoder){
return Member.builder()
.id(this.id)
.loginId(this.loginId)
.password(this.password)
.memberProfile(this.memberProfile)
.mainCardId(this.mainCardId)
.paymentPassword(passwordEncoder.encode(paymentPassword))
.userKey(this.userKey)
.deleted(this.deleted)
.build();
}
public boolean checkPaymentPassword(String rawPaymentPassword, PasswordEncoder passwordEncoder){
return paymentPassword == passwordEncoder.encode(rawPaymentPassword);
}
public Member updateMainCardId(UUID mainCardId){
return Member.builder()
.id(this.id)
.loginId(this.loginId)
.password(this.password)
.memberProfile(this.memberProfile)
.mainCardId(mainCardId)
.paymentPassword(this.paymentPassword)
.userKey(this.userKey)
.deleted(this.deleted)
.build();
}
//찾을 수 없다면 -1 반환
public int findMainCardIdx(List<Card> cards) {
for(int idx = 0, size = cards.size(); idx < size; idx++){
if(cards.get(idx).getId().equals(mainCardId)){
return idx;
}
}
return -1;
}
}
이펙티브 자바에서는 **"다 쓴 객체 참조를 해제하라"**고 한다.
User user = User.create(); // ① User 객체 생성
user = user.update();