냄새 19. 내부자 거래

    들어가기 전

    이 글은 인프런 백기선님의 강의를 복습하며 작성한 글입니다. 


    냄새 19. 내부자 거래 (Insider Trading)

    • '내부자 거래' 냄새는 다음 코드 형태를 의미한다.
      • 어떤 모듈이 다른 모듈의 내부 정보를 지나치게 많이 알고 있는 상태.
      • 이것은 모듈이 강하게 결합되어 있는 것을 의미함. 
    • 리팩토링 방법
      • 적절한 모듈로 '함수 옮기기'와 '필드 옮기기'를 사용해 결합도를 낮출 수 있다. (참조하는 필드 기준) 
      • 여러 모듈이 자주 사용하는 공통적인 기능은 새로운 모듈을 만들어 잘 관리하거나, '위임 숨기기'를 사용해 특정 모듈의 중재자처럼 사용할 수도 있다.
      • 상속으로 인한 결합도를 줄일 때는 '슈퍼클래스 또는 서브클래스를 위임으로 교체하기'를 사용할 수 있다. 

     


    코드로 살펴보기

    CheckIn 클래스를 살펴보자. CheckIn 클래스의 isFastPass()라는 메서드는 CheckIn 클래스에 있음에도 불구하고 Ticket의 내부정보에만 강하게 의존한다. 예를 들어 isFastPass()는 Ticket의 다음에 의존한다.

    • isPrime()
    • getPurhcaseDate()

    이것은 CheckIn 메서드가 Ticket의 내부에서 사용하는 메서드의 정보에 대해서 굉장히 많이 알고 있고, 이것이 '내부자 거래'에 해당하는 것을 의미한다. 

    public class CheckIn {
    
        public boolean isFastPass(Ticket ticket) {
            // isFastPass() 메서드는 ticket의 내부 정보(메서드)를 너무 많이 알고, 그것만 알고 있다.
            // 내부자 거래에 해당한다. (CheckIn이 Ticket에 강하게 의존함)
            LocalDate earlyBirdDate = LocalDate.of(2022, 1, 1);
            return ticket.isPrime() && ticket.getPurchasedDate().isBefore(earlyBirdDate);
        }
    }

    '내부자 거래'는 특정 클래스가 다른 클래스의 메서드만 일방적으로 참조하는 상태다. 다른 클래스의 정보만을 더 많이 참조하는데, 따라서 isFastPass()라는 메서드는 CheckIn 클래스가 아니라 Ticket 클래스로 이동되는 것이 더 적절하다. 따라서 '메서드 옮기기'를 통해서 '내부자 거래'를 적절하게 리팩토링 할 수 있다. 이를 통해 CheckIn 클래스 / 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() {
            // CheckIn 클래스에서 내부자 거래를 리팩토링해서 이 클래스로 이동된 메서드다.
            LocalDate earlyBirdDate = LocalDate.of(2022, 1, 1);
            return isPrime() && getPurchasedDate().isBefore(earlyBirdDate);
        }
    }
    
    public class CheckIn {
    
    }

    댓글

    Designed by JB FACTORY