if(acc.getMembership() == REGULAR && acc.getExpDate().isAfter(now())){
// 정회원 기능
}
위와 같은 정회원을 판별하는 로직이 있다고 가정하자.
그런데, 5년 이상 사용자에게 이벤트로 한달간 추가적으로 정회원 혜택을 주기위해 코드를 변경해야한다고 생각해보자.
if(acc.getMembership() == REGULAR &&
(
(acc.getExpDate().isAfter(fiveYearAgo) && acc.getExpDate().isAfter(now())) ||
(acc.getExpDate().isBefore(fiveYearAgo) && addMonth(acc.getExpDate()).isAfter(now()))
)){
// 정회원 기능
}
위와 같이 변경을 할 수 있는데, 여기서 문제점은 이 코드를 한 곳에서만 사용하고 있는게 아닐 것이라는 것이다.
그렇기 때문에, 변경해야하는 코드를 모두 찾아 변경해야한다는 문제가 생긴다.
→ 비용이 커진다.
요구 사항의 변화가 데이터 구조 및 사용에 변화를 발생시킨다.
요구 사항 변경의 예시
if(acc.hasRegularPermission()){
// 정회원 기능
}
public class Account {
private Membership membership;
private Date expDate;
public boolean hasRegularPermission(){
return membership == REGULAR && expDate.isAfter(now())
}
}
이때 요구 사항이 변경되면?
if(acc.hasRegularPermission()){ // 기능을 사용하는 코드는 그대로
// 정회원 기능
}
public class Account {
private Membership membership;
private Date expDate;
public boolean hasRegularPermission(){ // 내부 구현만 변경
return membership == REGULAR &&
(
expDate.isAfter(fiveYearAgo) && expDate.isAfter(now())) ||
expDate.isBefore(fiveYearAgo) && addMonth(expDate).isAfter(now()))
)
}
}
즉, 캡슐화는 연쇄적인 변경 전파를 최소화하게 됨.
acc.getExpDate().isAfter(now()); -> acc.isExpired()
Date date = acc.getExpDate();
date.isAfter(now); -> acc.isValid(now())