DEV ℧ Developer Diary

[Refactoring] 냄새 19. 내부자 거래

해당 포스트는 inflearn의 백기선님의 강의인 리팩토링 을 듣고 정리한 글입니다.

냄새 19. 내부자 거래

  • 어떤 모듈이 다른 모듈의 내부 정보를 지나치게 많이 알고 있는 코드 냄새. 그로인해 지나치게 강한 결합도(coupling)가 생길 수 있다.
  • 적절한 모듈로 “함수 옮기기 (Move Function)”와 “필드 옮기기 (Move Field)”를 사용해서 결합도를 결합도를 낮출 수 있다.
  • 여러 모듈이 자주 사용하는 공통적인 기능은 새로운 모듈을 만들어 잘 관리하거나, “위임 숨기기 (Hide Delegate)”를 사용해 특정 모듈의 중재자처럼 사용할 수도 있다.
  • 상속으로 인한 결합도를 줄일 때는 “슈퍼클래스 또는 서브클래스를 위임으로 교체하기”를 사용할 수 있다.

예제 코드

아래의 예제코드는 티켓을 체크인 할때의 기능을 구현한 로직이다.

  • CheckIn
public class CheckIn {
  public boolean isFastPass(Ticket ticket) {
    LocalDate earlyBirdDate = LocalDate.of(2022, 1, 1);
    return ticket.isPrime() && ticket.getPurchasedDate().isBefore(earlyBirdDate);
  }
}

해당 코드에서 눈여겨볼 점은 티켓이 빠르게 사용할 수 있는 티켓인지 여부를 판별하는 메소드 isFastPass에 대해서 확인해야 한다.

내부에서 티켓이 Prime 등급인지 또는, 티켓 구매일자를 조회하는등. CheckIn 클래스에서 Ticket의 정보를 너무 많이 사용하고 있는것을 볼 수있다.

이러한 경우에는 Ticket 클래스에 있는 것이 올바를 수도 있다.

  • Ticket
public class Ticket {

    private LocalDate purchasedDate;

    private boolean prime;

    public Ticket(LocalDate purchasedDate, boolean prime) {
        this.purchasedDate = purchasedDate;
        this.prime = prime;
    }

    public LocalDate getPurchasedDate() {
        return purchasedDate;
    }

    public boolean isPrime() {
        return prime;
    }

    public boolean isFastPass() {
        LocalDate earlyBirdDate = LocalDate.of(2022, 1, 1);
        return this.isPrime() && this.getPurchasedDate().isBefore(earlyBirdDate);
    }
}

이런식으로 옮긴다면, CheckIn에서 부적절하게 Ticket의 내부 정보를 꺼내서 참조할일이 없으니, 결합도가 많이 낮아지는 효과를 볼 수 있다.