티스토리 뷰

Java

[Java] Object 도서 정리(2)

joeylee 2020. 11. 23. 01:01

1. 영화 예매 시스템 구현하기

 

/**
 * 영화를 표현
 * 제목, 상영시간, 기본요금, 할인정책을 가지고 있음
 */
public class Movie {
    private String title;
    private Duration runningTime;
    private Money fee;
    private DiscountPolicy discountPolicy;

    public Movie(String title, Duration runningTime, Money fee, DiscountPolicy dIscountPolicy) {
        this.title = title;
        this.runningTime = runningTime;
        this.fee = fee;
        this.dIscountPolicy = dIscountPolicy;
    }

    public Money getFee() {
        return fee;
    }

    public Money calculateMovieFee(Screening screening) {
                if(discountPolicy == null) {
                        return fee;
                }     
        return fee.minus(discountPolicy.calculateDiscountAmount(screening));
    }
}

calculateMovieFee메소드는 가지고 있는 할인정책들에 상영정보를 전달해 할인요금을 계산하여

기존 요금에서 빼서 할인요금을 계산해줍니다

이때 할인정책이 없는 영화가 있어서 조건을 추가해줍니다

 

2. 무엇이 문제인가?

할인금액을 계산하는 책임이 DiscountPolicy의 자식 클래스에 있어야하는데

할인정책이 없을경우는 Movie쪽에 책임이 존재합니다

 

3.설계 계선하기

/**
 * 할인이없는 정책 표현
 */
public class NoneDiscountPolicy extends DiscountPolicy{
    @Override
    protected Money getDiscountAmount(Screening screening) {
        return Money.ZERO;
    }
}
Movie parasite = new ("기생충", Duration.ofMinutes(180), Money.wons(10000), new NoneDiscountPoilcy());

기존의 Movie와 DiscountPolicy를 수정하지 않고 NoneDiscountPolicy라는 새로운 클래스를 추가함으로써 어플리케이션의 기능을 확장했습니다

하지만 DiscountPolicy의 할인 조건이 없을 경우 getDiscountAmoun() 를 호출하지 않습니다

이것이 부모 클래스인 DIscountPolicy와 NoneDiscountPolicy를 개념적으로 결합시켰습니다

DiscountPolicy 클래스를 인터페이스로 변경합니다

 

public interface DiscountPolicy {
    Money calculateDiscountAmount(Screening screening);
}

 

원래 DiscountPolicy를 DefaultDiscountPolicy로 변경하고 인터페이스를 구현합니다

/**
 * 할인정책 표현
 * 할인조건들은 가지고 있음
 */
public abstract class DefaultDiscountPolicy implements DiscountPolicy {
    private List<DiscountCondition> conditions = new ArrayList<>();

    public DefaultDiscountPolicy(DiscountCondition ... conditions) {
        this.conditions = Arrays.asList(conditions);
    }

    @Override
    public Money calculateDiscountAmount(Screening screening) {
        for(DiscountCondition each : conditions) {
            if(each.isSatisfiedBy(screening)) {
                return getDiscountAmount(screening);
            }
        }
        return Money.ZERO;
    }

    protected abstract Money getDiscountAmount(Screening screening);
}

 

NoneDiscountPolicy가 DiscountPolicy 인터페이스를 구현 하도록 변경합니다

public class NoneDiscountPolicy implements DiscountPolicy {

    @Override
    public Money calculateDiscountAmount(Screening screening) {
        return Money.ZERO;
    }
}

 

이로써 개념적인 혼란과 결합을 제거 할수 있었지만

클래스 계층구조가 복잡해짐에 따라 읽기 쉽지 않습니다

 

결론

코드의 의존성과 실행 시점의 의존성이 다르면 다를수록 코드를 이해하기 어렵습니다
하지만 코드는 더 유연해지고 확장 가능해집니다

의존성의 양면성이 존재하니 트레이드오프하여 설계하자

'Java' 카테고리의 다른 글

[Java] Java 11 기능  (0) 2020.12.19
[Java] JVM 구조  (0) 2020.11.27
[Java] Object 도서 정리(1)  (0) 2020.11.23
[Java] 리액티브(reactive) 프로그래밍이란?  (0) 2020.11.23
[Java] 제이미터(jmeter)란?  (0) 2020.11.23
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함