데이터 중심 영화 예매 시스템 (이렇게 하면 안됨)
- 해당 챕터에서 데이터 중심으로 설계를 진행하면서 나쁜 예시를 보여준다
- 객체 내부에 저장되는 데이터를 기반으로 분할한다
ex) Movie.class
public class Movie {
private String title;
private Duration runningTime;
private Money fee;
private List<DiscountCondition> discountConditions;
private MovieType movieType;
private Money discountAmount;
private double discountPercent;
}
예약 관련 class
public class ReservationAgency {
public Reservation reserve(Screening screening, Customer customer, int audienceCount) {
Movie movie = screening.getMovie();
boolean discountable = false;
for(DiscountCondition condition : movie.getDiscountConditions()) {
if (condition.getType() == DiscountConditionType.PERIOD) {
discountable = screening.getWhenScreened().getDayOfWeek().equals(condition.getDayOfWeek()) &&
condition.getStartTime().compareTo(screening.getWhenScreened().toLocalTime()) <= 0 &&
condition.getEndTime().compareTo(screening.getWhenScreened().toLocalTime()) >= 0;
} else {
discountable = condition.getSequence() == screening.getSequence();
}
if (discountable) {
break;
}
}
Money fee;
if (discountable) {
Money discountAmount = Money.ZERO;
switch(movie.getMovieType()) {
case AMOUNT_DISCOUNT:
discountAmount = movie.getDiscountAmount();
break;
case PERCENT_DISCOUNT:
discountAmount = movie.getFee().times(movie.getDiscountPercent());
break;
case NONE_DISCOUNT:
discountAmount = Money.ZERO;
break;
}
fee = movie.getFee().minus(discountAmount);
} else {
fee = movie.getFee();
}
return new Reservation(customer, screening, fee, audienceCount);
}
}
- 코드를 다 올릴순 없지만 캡슐화 원칙이 위배되면서 여러 모듈의 결합도가 올라가는 것을 확인할 수 있었다
- 만약 discount 정책이 추가된다면? discount 와 관련된 모듈뿐만 아니라 다른 모듈(영화, 예약 등)도 전부 수정해야 했다
요약
단일 책임의 원칙 → 응집도 상승
책임 분산 → 응집도 하락, 변경 시 여러 모듈을 수정해야함
캡슐화 원칙 위배 → 응집도 하락 결합도 상승
- 책임을 나눠가짐으로써 응집도는 하락, 결합도 상승으로 새로운 기획으로 인한 유지보수 시 여러 모듈에 영항이 퍼짐
- 객체 외부로 내부의 구현을 드러내면 안됨
- getter setter이 메서드화 되어있어도 캡슐화에 전혀 도움되지 않음
- 파라미터를 통해, 혹은 메서드 자체를 통해 캡슐화를 위반할 수 있음
- 중요한건 내부 구현이 외부로 드러나지 않아야 한다는 것임
- 데이터 중심으로 생각한다면 아무리 개선해도 설계가 망가지게 되어있음
- → 너무 이른 시기에 데이터를 고민함
- 객체 내부 X 객체 외부에 초점을 맞추고 다른 객체와 협력하는 방법을 중점으로 생각해야함
결론 : 책임 중심으로 생각하고 설계해야함