본문 바로가기
책 정리/오브젝트

[책 오브젝트] CHAPTER4 - 설계 품질과 트레이드오프

by chanwoodev 2023. 6. 18.

데이터 중심 영화 예매 시스템 (이렇게 하면 안됨)

  • 해당 챕터에서 데이터 중심으로 설계를 진행하면서 나쁜 예시를 보여준다
  • 객체 내부에 저장되는 데이터를 기반으로 분할한다

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 객체 외부에 초점을 맞추고 다른 객체와 협력하는 방법을 중점으로 생각해야함

결론 : 책임 중심으로 생각하고 설계해야함