인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

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

qwerty1434님의 프로필 이미지
qwerty1434

작성한 질문수

오브젝트 - 기초편

할인 조건의 구현에 대해

해결된 질문

작성

·

38

1

안녕하세요. 좋은 강의 해주셔서 감사합니다. 덕분에 많이 배우고 있습니다.

SequenceCondition과 PeriodCondition 객체 구현(5-1)에 대해 궁금한 점이 있습니다. 

SequenceCondition

public class SequenceCondition implements DiscountCondition {
    private int sequence;

    @Override
    public boolean isSatisfiedBy(Screening screening) {
        return screening.isSequence(sequence);
    }
}

PeriodCondition

public class PeriodCondition implements DiscountCondition {
    private DayOfWeek dayOfWeek;
    private LocalTime startTime, endTime;

    public boolean isSatisfiedBy(Screening screening) {
        return  screening.getStartTime()
                .getDayOfWeek().equals(dayOfWeek) &&
                startTime.compareTo(screening.getStartTime().toLocalTime()) <= 0 &&
                endTime.compareTo(screening.getStartTime()
                        .toLocalTime()) >= 0;
    }
}

PeriodCondition의 isSatisfiedBy는 Screening이 알고 있는 정보에 대한 응답을 기반으로 스스로 할인 조건을 판단하고 있다고 느껴졌습니다.
반면에 SequenceCondition의 isSatisfiedBy는 Screening에게 isSequence메시지를 전송함으로써 결과적으로 '할인 조건의 만족 여부를 Screening이 판단하고 있는게 아닌가?'라는 생각이 들었습니다.


저는 Screening은 상영 회차(sequence)에 대한 정보를 알고 있고 이에 대답할 수 있기 때문에 Screening에게 상영 회차를 묻고 이를 바탕으로 SequenceCondition이 스스로 할인 조건을 판단하는 형태를 생각했는데요.

제가 생각한 SequenceCondition

public class SequenceCondition implements DiscountCondition {
    private int sequence;

    @Override
    public boolean isSatisfiedBy(Screening screening) {
        return sequence == screening.getSequence();
    }
}

이렇게 설계하니 또 Screening의 getSequence가 협력의 문맥을 고려하지 못한 채 만들어진거 같다는 느낌을 받았습니다.


이와 관련해 기존의 코드는 할인 조건의 여부를 SequenceCondition이 아닌 Screening이 판단하고 있다고 느껴지는데 이게 맞는건지, Screening의 isSequence는 어떤 요청에 의해 생성된 것인지, 그 외 여기에 대한 영호님의 생각과 의견이 궁금합니다!

답변 2

0

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

qwerty143님 안녕하세요.

강의가 도움이 되신다니 다행이네요. 🙂

좋은 질문 남겨주셔서 감사합니다.

 

ScreeningisSequece 메서드와 SequenceConditionisSatisfiedBy 메서드는 책임의 관점에서 의미가 다릅니다.

 

ScreeningisSequence 메서드는 회차가 동일한지를 판단합니다.

Screening의 입장에서 isSequence 메서드는 할인 여부와는 상관이 없습니다.

 

SequenceConditionisSatisfiedBy 메서드는 할인을 적용할 수 있는지 여부를 판단합니다.

회차가 동일할 경우 할인을 제공하기 때문에 ScreeningisSequnce 메서드를 재사용하고 있을 뿐입니다.

 

이런 의미적인 차이는 회차를 이용한 할인 여부 로직을 수정할 때 좀 더 명확해 지는데요

만약 특정한 요일의 특정 회차에만 할인을 적용해야 한다면 다음과 같이 SequenceConditionisSatisfiedBy 메서드를 수정하게 될것입니다.

아래 코드를 Screening에 구현하게 되면 Screening의 응집도가 낮아지게 됩니다.

public class SequenceCondition implements DiscountCondition {
  private int sequence;
  private DayOfWeek dayOfWeek;

  @Override
  public boolean isSatisfiedBy(Screening screening) {
    return screening.isSequence(sequence) && 
      screening.getStartTime().getDayOfWeek().equals(dayOfWeek);
  }
}

 

screening.getStartTime().getDayOfWeek(dayOfWeek)처럼 객체의 내부 속성을 연쇄적으로 가져오면 디미터 법칙(Law of Demeter)을 위반하기 때문에 객체의 인터페이스가 너무 복잡해지지 않는다면 screening.isScreenedOnDayOfWeek(dayOfWeek)과 같이 수정하는 것이 더 좋은 방법이기는 합니다.

 

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

qwerty1434님의 프로필 이미지
qwerty1434
질문자

isSatisfiedBy의 책임을 Screening에 넘기는게 아니라 isSatisfiedBy의 책임을 수행하기 위해 ScreeningisSequnce 메서드를 재사용하고 있는거였군요.

알려주신 답변 덕분에 어떤 내용인지 이해했습니다.

감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다. qwerty1434님께서 제기하신 질문은 설계 관점에서 매우 중요한 주제입니다. 이 질문을 통해 객체지향 설계의 핵심 개념인 “묻지 말고 시켜라” 원칙을 다시 한 번 생각해볼 수 있습니다.

문제 설명

qwerty1434님께서 지적하신 대로 SequenceCondition의 구현은 Screening에게 메시지를 보내어 조건의 만족 여부를 판단하고 있습니다. 이는 Screening 객체가 조건을 ‘알고’ 있다는 것을 전제로 하여, 이를 기반으로 결과를 판단하는 방식입니다.

반면 PeriodCondition은 특정 시간대를 정의하고, screening 데이터에 직접 접근하여 조건을 만족하는지 판단합니다. 이런 방식은 Screening의 내부 상태를 조건이 직접 사용하는 것이죠.

이론적 배경

“묻지 말고 시켜라” 원칙(Most Tell, Don’t Ask)은 객체에 필요한 정보를 요청하기보다는, 필요한 일을 시키도록 설계하는 방향을 권장합니다. 이를 통해 객체 간의 강한 결합을 피하고, 더 캡슐화된 객체 설계를 유지할 수 있습니다.

  1. isSequence의 존재 이유:

    • isSequence 메서드는 Screening 객체가 자신의 내부 상태에 관한 중요한 정보를 외부 객체가 요청하는 시점에 노출하지 않고, 메시지를 통해 필요한 결과를 반환하도록 설계된 것입니다. 이를 통해 다른 방법과의 결합도를 줄이며, Screening이 스스로 자신의 상태를 판단하여 외부에 필요한 정보를 제공합니다.
  2. SequenceCondition vs. PeriodCondition:

    • SequenceCondition에서는 조건 판단을 Screening에게 위임함으로써, Screening의 캡슐화를 유지합니다. 이는 메시지 중심의 설계를 지향합니다.
    • PeriodCondition에서는 Screening의 내부 상태(Time)을 직접적으로 가져와 판단함으로써 다소 결합도가 높아질 수 있는 부분이지만, 특정한 데이터 조건을 바탕으로 연산을 수행합니다.

관련 질문 및 논의

이와 비슷한 질문을 다룬 기존의 답변에서 DiscountConditionDiscountPolicy 간의 협력 및 설계 전략에 대해 더 깊이 있는 논의를 확인하실 수 있습니다.

qwerty1434님께서 느끼신 바와 같이 상영 순서에 대한 조건을 판단하는 방식은 설계 의도에 따라 변동될 수 있습니다. 객체지향의 핵심은 객체 간의 응집도와 결합도를 적절히 조정하여 유연하고 유지보수 가능한 구조를 갖추는 것입니다.

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

qwerty1434님의 프로필 이미지
qwerty1434

작성한 질문수

질문하기