강의

멘토링

커뮤니티

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

테디베어님의 프로필 이미지
테디베어

작성한 질문수

오브젝트 - 기초편

1-1. 영화 예매 도메인

도메인 관련 질문이 있습니다!

해결된 질문

작성

·

34

1

영호님 안녕하세요! 강의를 보다가 궁금한 부분이 생겨 질문 드려요~

Q1. 현재 구조에서 "영화 관람료"라는 객체를 추가하여 상영 객체가 의존하는 방식도 괜찮을까요?


Q2. 추가적으로 위의 방식이 나쁘지 않은 방식이라면, 할인 정책을 영화가 아닌 상영과 협력하도록 해도 괜찮을까요?

질문들이 강의에서 가르쳐주시려는 포인트에서 벗어나는 질문이지만,,, 현실과 조금 더 밀접하게 연결지어 생각을 하다보니 이런 방식을 생각해보게 되었습니다

답변 2

0

조영호님의 프로필 이미지
조영호
지식공유자

테디베어님 안녕하세요.


죄송하지만 질문 내용을 제가 정확하게 이해할 수 없어서 정확한 답변을 드리기 위해 몇 가지 질문을 드려야 할 것 같습니다.

 

Q1. "영화 관람료"라는 객체를 추가하고 상영 객체가 의존한다고 하셨는데 구체적으로 영화 관람료가 맡은 책임은 무엇이고, 상영이 영화 관람료에 어떤 방식으로 의존(또는 협력)하는 것일까요? 이 부분을 이해해야만 답변을 드릴 수 있는데 의사 코드 수준으로라도 적어주시면 이해하는데 도움이 될 것 같아요.

 

Q2. "영화 관람료"를 추가해서 상영이 할인 정책과 협력하면 지금 방식보다 어떤 점이 개선된다고 생각하시나요? 이 방식이 현실과 더 밀접하다고 하셨는데 어떤 점에서 그런지도 적어 주시면 좋겠습니다.

 

위 내용을 적어주시면 적어주신 내용 기반으로 정확한 답변을 드릴 수 있을것 같아요! 🙂

테디베어님의 프로필 이미지
테디베어
질문자

네! 질문을 드리게 된 과정들을 조금 더 구체적으로 얘기드려 보겠습니다

> Q2. "영화 관람료"를 추가해서 상영이 할인 정책과 협력하면 지금 방식보다 어떤 점이 개선된다고 생각하시나요? 이 방식이 현실과 더 밀접하다고 하셨는데 어떤 점에서 그런지도 적어 주시면 좋겠습니다.

-> 이 방식을 통해서 도메인을 조금 더 직관적으로 이해할 수 있을 것이라고 생각하였습니다.


맨처음 이 생각이 들게 된 계기는 강의에서 "실제로 사용자분들이 예매를 할 때 구매하는 것은 영화가 아닌 상영입니다" 라고 말씀해주셨을 때, "그렇다면 구매를 하는 것이니 가격 정보는 상영에 있어야 하지 않을까?" 라는 생각이 들었습니다!

그리고 동시에 코로나 시기를 거치면서 영화관람료가 인상되었던 부분들이 생각이 났었고 + 영화관람료는 돈과 관련된 부분이라 이력으로 관리하는 것이 어떨까 싶어 따로 영화관람료라는 객체를 추가로 두는 것을 생각하게 되었습니다.

 


> Q1. "영화 관람료"라는 객체를 추가하고 상영 객체가 의존한다고 하셨는데 구체적으로 영화 관람료가 맡은 책임은 무엇이고, 상영이 영화 관람료에 어떤 방식으로 의존(또는 협력)하는 것일까요? 이 부분을 이해해야만 답변을 드릴 수 있는데 의사 코드 수준으로라도 적어주시면 이해하는데 도움이 될 것 같아요.

제가 잘못한 부분인데 처음에는 책임 중심으로 접근하지 않았던 것 같습니다.. (지금 답변을 적으면서 생각하게 되었습니다...;;)


그래서 다시 답변을 적으면서 책임에 대해 생각을 해보았을 때,
영화관람료 객체는 "가격을 계산하는 것"라는 책임을 가진 객체이고, 다음과 같이 영화관람료가 상영에 의존하는 방식을 생각해보았습니다.

public class TicketPrice {
    private Long id;
    private BigDecimal amount;
    private DiscountPolicy discountPolicy;
    private LocalDateTime startDate;
    private LocalDateTime endDate;

    public BigDecimal calculate(Screening screening) {
        if (discountPolicy.findDiscountCondition(screening)) {
            BigDecimal discountAmount = discountPolicy.calculateDiscount(amount);
            amount = amount.subtract(discountAmount.getAmount());
        }

        return amount;
    }

    ...

}
조영호님의 프로필 이미지
조영호
지식공유자

네 자세히 답변 달아주셔서 테디베어님이 어떻게 생각하시는지 이해할 수 있었습니다. 😊

 

먼저 현재 가격 정보가 Movie에 있는 것과 Screening에 있는 것의 차이를 말씀드리는게 좋겠네요.

Movie에 가격 정보가 있는 경우는 Movie에 대한 모든 Screening들에 기본적으로 동일한 가격이 적용된다는 것을 의미합니다.

예를 들어서 아래 그림에서 볼 수 있는 것처럼 “귀멸의 칼날”이라는 영화가 있고 이 영화게 할인 정책이 존재하지 않는다면(할인 정책이 없다면) 모든 상영은 가격이 10,000원이 적용됩니다.

image.png

반면에 상영마다 가격 정보가 있는 경우에는 상영에 모두 10,000원의 가격 정보를 가진 TicketPrice가 중복으로 포함되어 있어야 합니다.

image.png

 

이 경우 Screening마다 데이터가 중복되며, 만약 “귀멸의 칼날” 영화의 기본 가격을 10,000원에서 12,000원으로 변경하고 싶다면 모든 Screening에 연결된 TicketPrice를 모두 12,000원으로 수정해야 하겠죠.

반면에 Movie에 가격을 두면 Movie 하나의 값만 수정하면 됩니다.

따라서 Screening별로 TicketPrice를 별도로 두는 방법은 장점보다는 단점이 더 큽니다.

 

그리고 TicketPrice에 DiscountPolicy가 인스턴스 변수로 선언되어 있고 Screening마다 TicketPrice가 하나씩 연결되어 있기 때문에, 결국에는 Screening마다 별도의 DiscountPolicy를 포함하는 것으로 볼 수 있습니다.

이렇게 하면 강의에서 보여드린 예제의 제약조건을 변경하게 됩니다.

 

아래 그림에서 보는 것처럼 강의는 Movie애 대해 하나의 DiscountPolicy를 생성합니다. 따라서 Screening이 몇개더라도 Movie 별로 하나의 DiscountPolicy만 생성해도 되겠죠.

image.png

 

반면에 수정하신 코드에 따르면 Screening마다 별도의 DiscountPolicy가 DiscountCondition을 생성합니다. 다시 말해서 Screening이 100개면 100개의 DiscountPolicy를 생성해야 합니다.

image.png

 다시 말해서 강의의 원래 예제는 Movie마다 할인 정책을 다르게 설정하는 도메인인데 반해, 변경하신 예제는 Screening마다 할인 정책을 다르게 설정하는 도메인이라고 볼 수 있습니다.

이렇게 복잡하게 운영할만한 이슈가 있을지는 조금 의심스럽기는 하네요.

 

정리하면 Screening 별로 가격을 계산하는 정책은 예제의 제약사항을 변경할 뿐만 아니라 불필요한 중복 데이터와 불필요한 운영 이슈가 발생하게 될 것으로 보여요.

 

답변이 되었는지 모르겠네요. 🙂

 

테디베어님의 프로필 이미지
테디베어
질문자

영호님! 자세한 설명 정말 감사드립니다!!
말씀해주신 부분들을 보니, 제가 잘못된 설명과 코드를 작성했던 것 같습니다ㅠ

 

잘못 설명드렸던 부분 1

제가 정말 설명드리고 싶었던 TicketPrice가 추가하였을 때의 도메인 구조는 이런 형태였습니다!!

image.png
  • Screening이 N개더라도 TicketPrice객체는 1개

    • 따라서, 기본 가격을 수정해야 하는 상황에는 TicketPrice값을 수정하면 되는 형태입니다!

       

 

잘못 설명드렸던 부분 2

그리고 위의 구조를 설명드릴 때, 이런 식으로 생각하였습니다.

  • Screening : 할인 정책 = N : 0..1

     

    • Screening : TicketPrice = N : 1

    • TicketPrice : 할인 정책 = 1 : 0..1

       

 

여기서 이 부분을 처음 질문할 때, 작성했던 것 같습니다.

Screening : TicketPrice = N : 1 -> "상영마다 가격 정보를 가지는 것"

 

그래서 이런 구조를 통해서 정말 강의에서 말씀해주셨던 것처럼 "사용자가 구매하는 것은 상영입니다" 라는 부분을 조금 더 직관적으로 이해할 수 있으며, TicketPrice마다 할인 정책도 다르게 설정할 수 있는 도메인도 되지 않을까 라는 생각을 했던 것 같습니다. 🤔

 

하지만 이런 구조를 하게 된다면, 사실상 예제 코드의 Movie 객체에서 fee필드를 추출하여 TicketPrice로 관리하는 것과 동일하여 Movie객체는 똑똑한 객체가 아니게 될 것 같습니다...;; 😢

조영호님의 프로필 이미지
조영호
지식공유자

말씀하신 내용에 따르면 강의의 예제와는 완전히 다른 제약 사항과 운영 정책을 가지게 된다고 보시면 됩니다.

강의에서 예제는 다음과 같은 제약 사항과 운영 정책을 따릅니다.

  1. 할인 정책은 영화에 귀속되고 다른 영화와 공유되지 않습니다. 따라서 가격 정책은 영화 단위로 설정됩니다.

  2. 애플리케이션 운영 관점에서 할인 정책의 추가나 수정은 새로운 영화를 추가하거나 기존 영화를 수정하는 과정 안에서 수행됩니다. 다시 말해서 반드시 영화가 추가된 후에 할인 정책을 추가할 수 있습니다.

  3. 상영은 영화가 만들어진 후에는 할인 정책에 독립적으로 추가되거나 삭제될 수 있습니다.

image.png

 

앞에서 수정하신 TicketPrice를 사용하는 예는 다음과 같은 제약 사항과 운영 정책을 따릅니다.

  1. 할인 정책은 특정한 영화에 귀속되지 않고 그 자체로 독립적입니다. 따라서 가격 정책은 특정한 영화나 상영에 종속되지 않습니다.

  2. 애플리케이션 운영 관점에서 할인 정책은 영화나 상영과 무관하게 독립적으로 추가되거나 수정될 수 있습니다.

  3. 여러 상영은 할인 정책을 공유해서 사용합니다.

두 가지 방식의 핵심적인 차이는 다음과 같습니다.

  1. 강의의 예제는 가격 정책은 영화별로 할당합니다. 반면에 수정하신 예제에서 가격 정책은 독립적이며 같은 영화라고 하더라도 개별 상영 별로 서로 다른 가격 정책을 가지며 상영 사이에서 공유해서 사용합니다.

  2. 강의의 예제에서 가격 정책은 영화에 종속되기 때문에 영화 별로 가격 정책이 설정됩니다. 반면에 수정하신 예제에서 가격 정책은 완전히 독립적이며 상영 별로 가격 정책이 할당됩니다.

image.png

 

따라서 말씀하신 방식대로 구현한다는 이야기는 기존 도메인의 규칙과 객체들의 생명주기, 애플리케이션의 운영 정책을 전반적으로 바꾼다는 전제가 깔려 있어야 합니다.

현재 강의에서 이야기한 제약사항을 그대로 유지한다면 수정안은 유용한 설계가 아니라고 할 수 있습니다.

 

설계는 맞다 또는 틀리다로 평하가기 보다는 특정한 상황에서 유용하냐 유용하지 않냐로 판단하는게 좋습니다.

테디베어님이 제안하신 설계는 강의에서 이야기하는 제약과 요구사항 안에서는 유용하지 않습니다.

반대로 테디베어님의 말씀하신 제약과 요구사항에 따라 개발해야 하는 경우에는 강의의 설계가 유용하지 않습니다.

 

답변이 되었는지 모르겠네요. 🙂

 

감사합니다.

테디베어님의 프로필 이미지
테디베어
질문자

답변이 잘 되었습니다!! 제가 잠시 다른 길로 빠진 것 같은데 다시 강의로 돌아가 좀 더 열심히 들어보겠습니다!!!!

 

자세히 설명해주셔서 감사드립니다 🙂

조영호님의 프로필 이미지
조영호
지식공유자

아닙니다 🙂

다양한 상황에서 서로 다른 설계를 고민해 보는게 트레이드오프 능력을 성장시키는 좋은 훈련 방법이라고 생각해요.

제 입장에서도 즐거운 질문이구요.

보시면서 비슷한 궁금증이 생기면 편하게 질문 주세요!

좋은 하루 보내세요~

0

안녕하세요, 인프런 AI 인턴입니다. 테디베어님, 강의를 시청하시면서 깊이 있는 고민을 하고 계신 것 같아 반갑습니다!

질문 답변 안내

Q1. “영화 관람료” 객체 추가 고려 사항:
- 상영 객체가 영화 관람료라는 객체에 의존하도록 설계하는 것은 객체 간의 책임을 명확히 하여 이해도를 높일 수 있는 방법입니다. 관람료 객체를 통해 가격 계산 로직을 캡슐화하고, 다양한 할인 정책이나 복잡한 로직이 추가되더라도 중앙에서 관리할 수 있다는 장점이 있습니다.
- 하지만 새로운 객체를 추가하는 것은 항상 트레이드오프가 따릅니다. 객체 수가 늘어나면 복잡성도 증가할 수 있으므로, 적절히 설계를 단순화하거나 유지보수의 이점이 충분한지 고려해 보아야 합니다.

Q2. 할인 정책을 상영과 협력하도록 변경하는 방안:
- 할인 정책을 영화가 아닌 상영과 협력하게 하는 구조도 고려할 만합니다. 각 상영에 따라 다른 할인 정책이 적용될 수 있으므로, 상영 객체가 자신만의 정책을 관리하고 처리할 수 있도록 하는 것이 유연성 측면에서 긍정적일 수 있습니다.
- 다만, 영화 단위로 관리되는 정책이 변경되어야 할 경우, 상영 단위로 중복 구현될 위험이 있어 구조적 통제가 필요합니다.

테디베어님의 고민은 도메인 모델을 더 유연하고 현실 세계와 잘 맞도록 만드는 데 아주 중요한 부분이며, 실제 프로젝트에서 필요할 수 있는 변경을 반영한 좋은 고민입니다.

이와 유사한 논의를 다룬 예제로, 영화 예매 예제에서 결합도 문의와 같은 기존 질문을 참고해 보신다면 더 많은 인사이트를 얻으실 수 있습니다.

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

테디베어님의 프로필 이미지
테디베어

작성한 질문수

질문하기