Skip to content
This repository was archived by the owner on Jan 11, 2026. It is now read-only.

[REFACTOR] 스터디 도메인 모델 구축#8

Merged
dvlp-sy merged 9 commits into
developfrom
SPOT-274/refactor
May 2, 2025
Merged

[REFACTOR] 스터디 도메인 모델 구축#8
dvlp-sy merged 9 commits into
developfrom
SPOT-274/refactor

Conversation

@dvlp-sy
Copy link
Copy Markdown
Collaborator

@dvlp-sy dvlp-sy commented May 2, 2025

#️⃣ 연관된 이슈

ex) #이슈 번호, #이슈 링크


🔎 작업 내용

기능에서 어떤 부분이 구현되었는지 설명해주세요.

디렉토리 계층 구조는 하단에 사진으로 첨부하였습니다!
이번 이슈에서는 Study 중심으로 Domain, Application, Presentation 패키지를 구분하여 정리하고, 직관적이지 않은 엔티티의 이름을 최대한 직관적으로 수정하는 데 집중했습니다.

  • Domain : Aggregate, Enums, Repository, Validation으로 구성되어 있습니다.

    • Aggregate : Root entity인 Study와 연관된 다른 entity가 너무 많아서 Aggregate 내에서도 카테고리(studymember, studypost, studyregion, studyschedule, studytheme, studytodo, studyvote)별로 분류했습니다...!
  • Application : 레거시 Service 코드와 ServiceImpl 코드를 옮겨 두었습니다. 현재 서비스가 적절하게 분류가 되어 있지 않아서 Aggregate에서 분류한 카테고리대로 서비스 코드도 분리할 예정입니다.

  • Presentation : 레거시 Controller 코드와 DTO 코드를 옮겨 두었습니다.

    • Controller : 컨트롤러도 서비스와 마찬가지로 적절하게 분류가 되어 있지 않아서 Aggregate에서 분류한 카테고리대로 컨트롤러 코드를 분리할 예정입니다.

    • DTO : 하위 패키지로 request와 response를 그대로 유지하였습니다. DTO의 경우 너무 많이 분리가 되어 있어서 추후 Aggregate에서 분류한 카테고리대로 DTO를 통합하고 정리하는 과정을 수행할 예정입니다.


📷 스크린샷 (선택)

작업한 결과물에 대한 간단한 스크린샷을 올려주세요.

스크린샷 2025-05-02 오후 4 16 39

💬리뷰 요구사항 (선택)

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요.

DDD는 저도 처음 해보는 거라 잘못된 부분이 있을 수도 있어서 같이 검토해주시면 감사하겠습니다~!!

앗 그리고 기존의 ReasonStudy 엔티티는 StudyJoinReason으로 이름을 변경하고 Member Domain으로 이동시켰습니다.
스터디 참여 이유는 스터디보다 회원한테 종속되는 게 더 맞는 것 같아서 일단 요렇게 바꿔놨는데 혹시 다르게 생각하시면 말씀해주세용 😎

@dvlp-sy dvlp-sy added the ♻️ refactor Code Refactoring label May 2, 2025
@dvlp-sy dvlp-sy requested review from FromKyoung and msk226 May 2, 2025 07:34
@dvlp-sy dvlp-sy self-assigned this May 2, 2025
@dvlp-sy dvlp-sy linked an issue May 2, 2025 that may be closed by this pull request
@dvlp-sy
Copy link
Copy Markdown
Collaborator Author

dvlp-sy commented May 2, 2025

테스트 오류 수정해서 다시 올려놓겠습니다 XD

Copy link
Copy Markdown
Member

@msk226 msk226 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

허허... StudyReason을 제가 깜빡했군요..! 감사합니다...

그리고 저도 이제 막 공부하고 있는 입장이라 아직 개념이 잘 정립이 되질 않네요...!

지난 PR에서 말씀 드렸던 기준으로 애그리거트 경계 판단을 하려고 하니 모호한 부분들이 굉장히 많이 존재했습니다!

제가 생각했던 기준으로 스터디를 바라봤을 때, 스터디 회원, 퀴즈, 투두 등 모든 연관 도메인 엔티티는 스터디 애그리거트에 속해야 하지만, 이런 도메인 엔티티들은 삭제 생명주기를 함께할 뿐, 별도의 비즈니스 로직을 가지고 있는 별도의 애그리거트로 봐야 하지 않을까 하는 질문이 저도 모르게 떠오르더라구요!

스터디 지역 및 테마는 별도의 비즈니스 로직도 없고, 스터디가 생성될 때 함께 생성되고, 거의 모든 생명주기를 함께하기 때문에 이 둘은 스터디 애그리거트에 속하는 게 맞다고 생각합니다.

반면, 스터디 회원, 투두, 게시글 등 각자의 비즈니스 로직을 갖고 있는 도메인 엔티티들은 별도의 애그리거트로 봐야 하지 않을지 생각이 드네요! 비즈니스 일관성의 범위도 다르고, 얘들을 다 묶어버리면 스터디 애그리거트가 너무 비대해지지 않을까 하는 걱정도 생깁니다. 예를 들어 투두 생성과 스터디 수정이 하나의 트랜잭션으로 묶일 필요는 없잖아요!

그래서 이런 도메인 엔티티들은 분리하는 게 맞지 않을까 하는 생각이 듭니다!

스터디 회원과 같은 강한 일관성이 필요한 범위마다 애그리거트를 나누고, StudyId를 참조하는 방식으로 연결하는 것이 더 나은 방법 같아요!

다음은 예시입니다!

@Getter
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class StudyMember extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false, length = 20)
    private StudyApplicationStatus status;

    @Column(nullable = false, columnDefinition = "BIT DEFAULT 0")
    private boolean isOwned;

    @Column(columnDefinition = "text")
    private String introduction;

    @Column(columnDefinition = "text")
    private String reason;

    // 엔티티 참조 대신 ID만 보관
    @Column(nullable = false)
    private Long memberId;

    @Column(nullable = false)
    private Long studyId;

https://jaehoney.tistory.com/223 ID를 이용한 애그리거트 참조 부분 참고하시면 더 잘 정리되어 있으니 읽어보셔도 좋을 것 같습니당

++ 당장 이렇게 바꾸자는 것은 아니고, 추후에 이런 식으로 바꿔가면 어떨까 하는 생각이 들어서 말씀드렸어요!

@dvlp-sy
Copy link
Copy Markdown
Collaborator Author

dvlp-sy commented May 2, 2025

허허... StudyReason을 제가 깜빡했군요..! 감사합니다...

그리고 저도 이제 막 공부하고 있는 입장이라 아직 개념이 잘 정립이 되질 않네요...!

지난 PR에서 말씀 드렸던 기준으로 애그리거트 경계 판단을 하려고 하니 모호한 부분들이 굉장히 많이 존재했습니다!

제가 생각했던 기준으로 스터디를 바라봤을 때, 스터디 회원, 퀴즈, 투두 등 모든 연관 도메인 엔티티는 스터디 애그리거트에 속해야 하지만, 이런 도메인 엔티티들은 삭제 생명주기를 함께할 뿐, 별도의 비즈니스 로직을 가지고 있는 별도의 애그리거트로 봐야 하지 않을까 하는 질문이 저도 모르게 떠오르더라구요!

스터디 지역 및 테마는 별도의 비즈니스 로직도 없고, 스터디가 생성될 때 함께 생성되고, 거의 모든 생명주기를 함께하기 때문에 이 둘은 스터디 애그리거트에 속하는 게 맞다고 생각합니다.

반면, 스터디 회원, 투두, 게시글 등 각자의 비즈니스 로직을 갖고 있는 도메인 엔티티들은 별도의 애그리거트로 봐야 하지 않을지 생각이 드네요! 비즈니스 일관성의 범위도 다르고, 얘들을 다 묶어버리면 스터디 애그리거트가 너무 비대해지지 않을까 하는 걱정도 생깁니다. 예를 들어 투두 생성과 스터디 수정이 하나의 트랜잭션으로 묶일 필요는 없잖아요!

그래서 이런 도메인 엔티티들은 분리하는 게 맞지 않을까 하는 생각이 듭니다!

스터디 회원과 같은 강한 일관성이 필요한 범위마다 애그리거트를 나누고, StudyId를 참조하는 방식으로 연결하는 것이 더 나은 방법 같아요!

다음은 예시입니다!

@Getter

@Entity

@NoArgsConstructor(access = AccessLevel.PROTECTED)

public class StudyMember extends BaseEntity {



    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    private Long id;



    @Enumerated(EnumType.STRING)

    @Column(nullable = false, length = 20)

    private StudyApplicationStatus status;



    @Column(nullable = false, columnDefinition = "BIT DEFAULT 0")

    private boolean isOwned;



    @Column(columnDefinition = "text")

    private String introduction;



    @Column(columnDefinition = "text")

    private String reason;



    // 엔티티 참조 대신 ID만 보관

    @Column(nullable = false)

    private Long memberId;



    @Column(nullable = false)

    private Long studyId;

https://jaehoney.tistory.com/223 ID를 이용한 애그리거트 참조 부분 참고하시면 더 잘 정리되어 있으니 읽어보셔도 좋을 것 같습니당

++ 당장 이렇게 바꾸자는 것은 아니고, 추후에 이런 식으로 바꿔가면 어떨까 하는 생각이 들어서 말씀드렸어요!

저도 이 부분에 대해서 굉장히 고민이 많았는데요!! 이걸 과연 하나의 애그리거트로 보는 게 맞나 싶더라구요 😂 그렇다고 Study의 하위 엔티티인 StudyPost를 별도로 두는 것도 애매하고....

마커스님 말씀처럼 어차피 StudyPost, StudySchedule, StudyVote가 별도의 비즈니스 로직이라면 엔티티명을 좀 바꿔서 대등한 애그리거트로 두는 방향은 어떨까요?? Study, Story(StudyPost), Schedule, Vote, Theme, ToDo 이런 식으로요! 직관성이 조금 떨어지긴 하지만 저희 앱이 "스터디" 앱이니까 Schedule이라고만 써도 대충 스터디 관련 일정일 거라고 유추할 수 있을 것 같아서요..!

@msk226
Copy link
Copy Markdown
Member

msk226 commented May 2, 2025

허허... StudyReason을 제가 깜빡했군요..! 감사합니다...
그리고 저도 이제 막 공부하고 있는 입장이라 아직 개념이 잘 정립이 되질 않네요...!
지난 PR에서 말씀 드렸던 기준으로 애그리거트 경계 판단을 하려고 하니 모호한 부분들이 굉장히 많이 존재했습니다!
제가 생각했던 기준으로 스터디를 바라봤을 때, 스터디 회원, 퀴즈, 투두 등 모든 연관 도메인 엔티티는 스터디 애그리거트에 속해야 하지만, 이런 도메인 엔티티들은 삭제 생명주기를 함께할 뿐, 별도의 비즈니스 로직을 가지고 있는 별도의 애그리거트로 봐야 하지 않을까 하는 질문이 저도 모르게 떠오르더라구요!
스터디 지역 및 테마는 별도의 비즈니스 로직도 없고, 스터디가 생성될 때 함께 생성되고, 거의 모든 생명주기를 함께하기 때문에 이 둘은 스터디 애그리거트에 속하는 게 맞다고 생각합니다.
반면, 스터디 회원, 투두, 게시글 등 각자의 비즈니스 로직을 갖고 있는 도메인 엔티티들은 별도의 애그리거트로 봐야 하지 않을지 생각이 드네요! 비즈니스 일관성의 범위도 다르고, 얘들을 다 묶어버리면 스터디 애그리거트가 너무 비대해지지 않을까 하는 걱정도 생깁니다. 예를 들어 투두 생성과 스터디 수정이 하나의 트랜잭션으로 묶일 필요는 없잖아요!
그래서 이런 도메인 엔티티들은 분리하는 게 맞지 않을까 하는 생각이 듭니다!
스터디 회원과 같은 강한 일관성이 필요한 범위마다 애그리거트를 나누고, StudyId를 참조하는 방식으로 연결하는 것이 더 나은 방법 같아요!
다음은 예시입니다!

@Getter

@Entity

@NoArgsConstructor(access = AccessLevel.PROTECTED)

public class StudyMember extends BaseEntity {



    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)

    private Long id;



    @Enumerated(EnumType.STRING)

    @Column(nullable = false, length = 20)

    private StudyApplicationStatus status;



    @Column(nullable = false, columnDefinition = "BIT DEFAULT 0")

    private boolean isOwned;



    @Column(columnDefinition = "text")

    private String introduction;



    @Column(columnDefinition = "text")

    private String reason;



    // 엔티티 참조 대신 ID만 보관

    @Column(nullable = false)

    private Long memberId;



    @Column(nullable = false)

    private Long studyId;

https://jaehoney.tistory.com/223 ID를 이용한 애그리거트 참조 부분 참고하시면 더 잘 정리되어 있으니 읽어보셔도 좋을 것 같습니당
++ 당장 이렇게 바꾸자는 것은 아니고, 추후에 이런 식으로 바꿔가면 어떨까 하는 생각이 들어서 말씀드렸어요!

저도 이 부분에 대해서 굉장히 고민이 많았는데요!! 이걸 과연 하나의 애그리거트로 보는 게 맞나 싶더라구요 😂 그렇다고 Study의 하위 엔티티인 StudyPost를 별도로 두는 것도 애매하고....

마커스님 말씀처럼 어차피 StudyPost, StudySchedule, StudyVote가 별도의 비즈니스 로직이라면 엔티티명을 좀 바꿔서 대등한 애그리거트로 두는 방향은 어떨까요?? Study, Story(StudyPost), Schedule, Vote, Theme, ToDo 이런 식으로요! 직관성이 조금 떨어지긴 하지만 저희 앱이 "스터디" 앱이니까 Schedule이라고만 써도 대충 스터디 관련 일정일 거라고 유추할 수 있을 것 같아서요..!

좋아요! 동의합니다!

@dvlp-sy dvlp-sy merged commit b88b7a6 into develop May 2, 2025
1 check passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

♻️ refactor Code Refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REFACTOR] 스터디 도메인 모델 구축

2 participants