책임주도설계는 익숙해지기위해서 부단한 노력과 시간이 필요하다.
( 매 우 어 렵 다 )
이럴때는 최대한 빠르게 목적한 기능을 수행하는 코드를 작성하는 것이다.
일단 코드상에 명확하게 드러나는 책임들을 보고 협력과 책임에 관해 고민하면서 책임들을 올바른 위치로 옮기는 것이다.
주로 객체지향 설계에 대한 경험이 부족한 개발자들과 페어 프로그래밍을 할때나 설계의 실마리가 풀리지 않을때 이런 방법을 사용하는데 생각보다 훌륭한 설계를 얻게 되는 경우가 종종 있다.
주의할 점은 코드를 수정 한 후에 겉으로 드러나는 동작이 바뀌어서는 안된다는 것이다.
캡슐화를 향상 시키고 응집도를 높이고 결합도를 낮춰야 하지만 동작은 그대로 유지해야 한다.
이처럼 이해하기 쉽고 수정하기 쉬운 소프트웨어로 개산하기위해 겉으로 보이는 동작은 바꾸지 않은채 내부 구조를 변경하는 것을 리팩토링 이라고 부른다.
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).times(audienceCount);
} else {
fee = movie.getFee().times(audienceCount);
}
return new Reservation(customer, screening, fee, audienceCount);
}
}
단점
한마디로 말해서 응집도가 낮아서 이해하기도 어렵고 재사용하기도 어려우며 변경하기도 어렵다 이러한 메소드를 몬스터 메소드라고 부른다.
우선 메소드를 작게 분리해서 메소드의 응집도를 높여라.
응집도가 높은 메소드는 변경되는 이유가 단 하나여야 한다.