-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEAT]: 프로필 수정 api 구현 #62
Conversation
|
||
@Entity | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@EqualsAndHashCode(callSuper = false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lombok을 사용해 equals, hashcode 를 재정의 했습니다.
@Column(name = "personality") | ||
private List<Personality> personalities = new ArrayList<>(); | ||
@Embedded | ||
private Profile profile; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
유저의 프로필 관련 정보를 임베디드 타입으로 선언하였습니다. 이유는 프로필 수정 시 필드 업데이트 로직을 분리하기 위함입니다.
private String introduce; | ||
|
||
@Convert(converter = EnumArrayConverter.class) | ||
@Default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@builder 사용 시 초기값을 무시하기 때문에, @Builder.Default 어노테이션을 사용해 초기값을 설정해줬습니다.
수고하셨습니다!!
|
@Embeddable | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public class Profile { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Profile
이라는 개념을 따로 빼어 User내의 값 객체로 둔거는 좋은 것 같습니다.
하지만 값 객체는 가변성이 있을 경우 많은 문제 상황이 발생할 수 있습니다. 따라서 불변객체로 만드는 것을 지향합니다.
이를 setter 같은 함수를 사용하지 않고 불변객체로 만들어 보면 어떨까요?
또한 이 객체가 생성될 때 불변식을 검증하는 로직도 들어갔으면 좋겠습니다!!..
예를들어 Personality의 갯수는 3개여야 한다든가..등등....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
불변객체 너무 좋네요. 사실 메모리 누수 문제로 고민하고 있었는데, 단점보다 장점이 더 큰거 같네요 바로 반영하겠습니다 🫡
기획 확인 후 불변식 검증도 반영해볼게요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
validation을 활용해 request dto를 검증했습니다
personalities
: 3개 이상introduce
: notBlankname
: notBlank
User user = userFindService.findById(userId); | ||
Profile profile = user.getProfile(); | ||
|
||
profile.setProfile( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
앞의 불변객체에 대한 수정 후 이 부분의 코드를 좀 더 선언적으로 작성하는 건 어떨까요?
UserUpdateService
의 입장에서는 User에
대한 Profile
을 어떻게 update 하는지에 대해서는 별로 궁금하지 않고, 무엇을 하는지에 대해서만 궁금할거에요. 이 부분은 1. user에서 profile을 찾고(user.getProfile()) 2. proflie을 update(profile.setProfile()) 하겠다라고 어떻게 하는지에 초점이 맞춰져 있는 것 같애요.
또한 Profile은 User내의 소속되어 있는 값 객체입니다. 이렇게 User 외부에 Profile을 명시적으로 처리하는 것은 캡슐화와 은닉화를 지키지 못한 것 같애요!(Profile에 대한 처리는 User 내부에서 처리하도록 해서 캡슐화 및 은닉화...! -> 외부에서는 user의 무엇을에만 관심이 있겠죠?!) 따라서 아래와 같이 수정하는 건 어떨까요???!?
user.updateProfile(request.getImageUrl, request.Name, ....);
updateProfile
메소드 내부에는 새로운 Profile 값 객체를 생성한 후 profile 필드 갈아 끼우는 로직...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Profile을 어떻게 update 하는지에 대해서는 별로 궁금하지 않고, 무엇을 하는지에 대해서만 궁금할거에요.
!! 오 너무나도 맞는말이네요. 프로필 데이터 업데이트 로직을 분리하는 것이 좋을거 같습니다.
그리고, 제 생각에는 user 내부에서 프로필 객체를 생성하고 업데이트하는 것 또한, 관심사 분리가 필요한거 같아요. 어떤 프로필인지는 궁금하지 않을거 같다는 생각입니다! (user.updateProfile 메소드 내 프로필 객체 생성 로직)
따라서, 프로필 업데이트에 대한 domain service를 생성해 domain service 내부에서 Profile 객체를 생성하고, user.updateProfile(Profile profile)
을 호출하는 것은 어떨까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Profile
객체는 불변객체이기 때문에 업데이트 에 대한 domain service는 따로 두지 말고 기존에 두었던 ProfileFactory
domain service를 재활용하면 될 것 같습니다.
새로운 Profile 생성 -> User의 Profile 갈아 끼우기
이를 구현할 때는
Service단에 명시적으로 Profile은 생성한 후 user.updateProfile(proflie); 를 하는 방법이 있을 것 같구
// Service 단
Profile profile = profileFactory.create(profileDto);
user.updateProfile(profile);
Profile
에 대한 노출을 외부(여기에서는 Servcie단 이겠죵?)에 시키지 않고 User 내부에서 새로운 Profile에 대한 생성을 처리할 수 있을 것 같습니다.(은닉화)
//Service 단
user.updateProfile(profileFactory, profileDto);
두개의 방법을 활용하거나 하늘님의 개인적으로 생각나는 방법으로 수정해주시구 그렇게 수정한 이유를 커멘트 달아주세용!@~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
user.updateProfile(profileFactory, profileDto)
위 코드의 경우, 관심사 분리의 목적과는 맞지 않다고 생각했어요. 제가 생각한 user의 관심사는 [user는 어떤 프로필 객체인지 궁금하지 않고, 프로필 필드를 교체하는 것에만 관심이 있다] 였습니다. 위 코드도 결과적으로는 user.updateProfile 메서드 내부에서 프로필 객체를 생성하기 때문에 관심사 분리의 목적과 맞지 않다고 생각했습니다.
하지만, 제가 생각하는 관심사 분리를 위해선 profile 값 객체가 외부에 노출되어야 했고, 지환님이 말씀해주신 것처럼 은닉화 및 캡슐화에 위배되는 로직이 될 수 밖에 없다고 생각했어요.
따라서 관심사 분리보다는 캡슐화, 은닉화가 객체지향 프로그래밍에서 더 중요한 개념이라고 생각해 아래와 같이 수정했습니다.
public void updateProfile(String imageUrl, String nickname, LocalDate birth,
Gender gender, String introduce, List<Personality> personalities
) {
this.profile = Profile.builder()
.imageUrl(imageUrl)
.nickname(nickname)
.birth(birth)
.gender(gender)
.introduce(introduce)
.personalities(personalities)
.build();
}
사실 맨 처음 지환님이 제안한 코드입니다 ㅎㅎㅎ
덕분에 객체지향 프로그래밍에 대해 더 깊게 고민해볼 수 있었어요 ~~~!
감사합니다 머지 고?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고고~
[FEAT]: Security Filter 단 예외 핸들링 (JWT)
Issue number
작업 사항