inflearn logo
강의

講義

知識共有

トビーのクリーン・スプリング - ドメインモデルパターンとヘキサゴナルアーキテクチャ Part 2

講義ドメイン開発 (1)

내부 객체 직접 접근에 관하여.

9

javython

投稿した質問数 3

0

토비님 안녕하세요!

좋은 강의 만들어 주셔서 감사합니다.


객체지향 프로그래밍에서는 객체의 내부 구현이나 구조를 외부에서 직접 알 필요가 없도록 캡슐화하고, 객체의 행동을 통해 상호작용하는 것​이 중요하다고 알고 있습니다.

기존 테스트에서는 Course 내부의 detail 객체에 직접 접근합니다. 이를 아래와 같이 수정해봤습니다.


public class Course extends AbstractEntity {
    public LocalDateTime getPublishedAt() {
        return detail.getPublishedAt();
    }
}
@Test
void publish() {
    course.submitForReview();
    course.publish();

    assertThat(course.getStatus()).isEqualTo(CourseStatus.PUBLISHED);
    //assertThat(course.getDetail().getPublishedAt()).isNotNull();
    assertThat(course.getPublishedAt()).isNotNull();

    assertThatThrownBy(() -> course.publish())
        .isInstanceOf(IllegalStateException.class);
}

이러한 판단이 객체지향의 캡슐화, 정보 은닉 관점에서 올바른지 궁금합니다.


java spring spring-boot jpa 리팩터링 ddd

回答 1

0

communityai8509

안녕하세요, 인프런 AI 인턴입니다. 잉여인간님!

질문하신 것처럼 Course 외부에서 내부 객체인 detail에 직접 접근하지 않고, Course가 필요한 정보를 제공하도록 만드는 방식은 캡슐화와 정보 은닉 관점에서 적절한 방향입니다.

course.getDetail().getPublishedAt()처럼 내부 구조를 외부에 노출하면 테스트나 사용하는 코드가 Course 내부에 detail 객체가 존재한다는 사실을 알아야 합니다. 이후 detail의 구조가 변경되면 외부 코드와 테스트도 함께 수정해야 할 수 있습니다.

반면 다음과 같이 Course가 위임 메서드를 제공하면 외부에서는 Course의 내부 구조를 알 필요가 없습니다.

public LocalDateTime getPublishedAt() {
    return detail.getPublishedAt();
}

다만 단순히 값을 반환하는 getter를 추가하는 것보다, 외부에서 정말 필요한 의미를 메서드로 표현하는 방법도 고려할 수 있습니다.

public boolean isPublished() {
    return status == CourseStatus.PUBLISHED;
}

public boolean hasBeenPublished() {
    return detail.getPublishedAt() != null;
}

즉, 테스트가 publishedAt이라는 내부 데이터 자체를 검증해야 하는 경우에는 getPublishedAt()도 괜찮지만, 비즈니스 관점에서 “강의가 이미 발행되었는가?”를 확인하는 것이 목적이라면 isPublished()와 같은 도메인 행동 또는 질의 메서드가 더 명확할 수 있습니다.

이와 관련해 애그리거트 내부 엔티티나 값에 접근할 때의 기준을 설명한 기존 답변을 참고해 보시면 도움이 됩니다.

개인적질문 - 애그리거트 루트와 내부 객체 접근 기준

기존 답변에서도 단순 조회라면 내부 값을 조회할 수 있지만, 변경이나 조건 판단 같은 로직은 애그리거트 루트에 두고 루트가 필요한 기능을 수행하도록 하는 것이 바람직하다고 설명하고 있습니다. 이렇게 하면 내부 구조가 변경되어도 외부 코드의 영향을 줄이고, 도메인 규칙을 Course 안에서 일관되게 관리할 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

라이브 강의 영상 녹화본이 있을까요?

0

15

0

presentation error

0

13

1

인증이 늦었습니다ㅜㅜ 확인부탁드립니다

0

31

1

9월 8일 세션 진행한 거는 없었을까요

0

24

1

CertificationServiceTest

0

24

1

FlushModeType.COMMIT (12:45) 예시코드 질문

0

20

1

미션1 진행방법 관련

1

23

1

클로드코드 명령어 - 대화&세션관리부분 강의자료 빈폴더

0

27

1

Spock given and가 검증을 하는지

0

23

1

9번 강의 save 메서드 질문

0

28

1

Issuance 테이블에 status, couponId 인덱스가 꼭 필요할까요?

2

37

1

readme에 대한 자료는 따로 받아볼수 있나요?

0

36

2

11강 따라하는중에 오류가 발생해서 문의드립니다.

0

33

1

InvalidCurriculumException DIP 적용 여부 문의

0

30

1

ProductController 에서 타협하지 않는다면 어떤 형태가 되나요?

1

37

2

섹션2, 대화&세션관리 수업 자료 누락

0

38

2

영상 다운로드는 안되나요?

0

47

1

IntelliJ IDEA 체험 만료

0

46

2

부하 테스트 시 설정 관련 질문드립니다

1

68

2

HelloSpringApplication.java 클래스 실행 오류

0

46

1

build 시 에러 해결방법 공유(docker.desktop 업데이트 -> 의존성 버전 수정)

0

63

2

설계 트레이드 오프 링크 접속 안됨

0

93

2

헥사고날 아키텍처와 DDD를 적용할 때, 화면에 강하게 연관된 조회 데이터를 어떻게 다루는 게 좋은지 궁금합니다.

0

143

2

Request DTO에서 Entity를 생성할 때 의존성 방향을 반대로 하면 어떨까요?

0

130

2