리팩토링 8. 매개변수 객체 만들기

    들어가기 전

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


    리팩토링 8. 매개변수 객체 만들기 (Introduce Parameter Object)

    • 같은 매개변수들이 여러 메소드에 걸쳐 나타난다면 그 매개변수들을 묶은 자료 구조로 만들 수 있다. 
    • 그렇게 만든 자료구조는
      • 해당 데이터 간의 관계를 보다 명시적으로 나타낼 수 있다.
      • 함수에 전달할 매개변수 개수를 줄일 수 있다.
      • 도메인을 이해하는데 중요한 역할을 하는 클래스로 발전할 수도 있다. (프로그램이 하는 일을 좀 더 쉽게 이해할 수 있도록 도와준다)

    비슷한 매개변수들이 여러 메서드에 같이 전달되는 경우가 많을 수 있다. 이런 경우라면, 이 매개변수들은 서로 관계를 가지고 있는 매개변수로 이해할 수 있다. 이런 매개변수들이라면 하나의 인스턴스로 묶어주는 것이 데이터 의미를 잘 나타내는데 도움이 될 수 있다. 또한, 이후에는 단순히 DTO가 아니라 하나의 도메인 클래스로 발전할 가능성 역시 존재한다.

    예를 들어 시작은 DTO, record 타입이지만, 하는 일이 점점 커져서 메서드가 추가되면서 도메인 클래스가 될 수도 있다.


    Before

    아래 코드를 살펴보면 현재 totalNumberOfEvents와 p라는 값이 함께 매개변수로 메서드에 넘어가는 경우가 잦은 것을 볼 수 있다. 따라서 이 객체들을 ParticipantPrinter 라는 Record로 묶어줄 수 있다. Record로 묶어준다면 불변성을 제공해주며, 메서드에 전달되는 매개변수를 줄일 수 있게 된다.  따라서 이곳에서는 다음 리팩토링을 실행한다

    • totalNumberOfEvents / p 값을 묶은 ParticipantPrinter Record 생성. 
    • 각 메서드에서 ParticipantPrinter Record를 받도록 리팩토링. 
    // p, totalNumberOfEvents가 함께 다니는 경우가 많다.
    private double getRate(int totalNumberOfEvents, Participant p) {
        long count = p.homework().values().stream()
                .filter(v -> v == true)
                .count();
        double rate = count * 100 / totalNumberOfEvents;
        return rate;
    }
    
    // p, totalNumberOfEvents가 함께 다니는 경우가 많다.
    private String getMarkdownForParticipant(int totalNumberOfEvents, Participant p) {
        return String.format("| %s %s | %.2f%% |\n", p.username(), checkMark(p, totalNumberOfEvents), getRate(totalNumberOfEvents, p));
    }

    After

    위에서 이야기 한 것처럼 전달되는 매개변수를 2개 → 1개로 줄였다. 이 때 totalNumberOfEvents와 p 객체를 ParticipantPrinter 객체로 묶어서 전달하는 방법으로 접근했다. 

    private double getRate(ParticipantPrinter participantPrinter) {
        ...
    }

    ParticipantPrinter 객체는 다음과 같이 작성되었다. 

    public record ParticipantPrinter(int totalNumberOfEvents, Participant participant) {
    }

    FuthreMore. 매개변수 필드로 만들기 (Introduce Field)

    앞서서는 함께 등장하는 매개변수들을 묶어서 전달되는 매개변수를 줄이는 방법을 접근했다. 이와는 조금 다른 발상이지만, 많은 메서드에 공통적으로 전달되는 매개변수가 있다면 클래스 변수로 빼서 매개변수를 줄이는 방법도 존재한다. 

    // 자주 전달되는 매개변수를 필드로 빼서, this로 참조해서 매개변수를 줄임. 
    public class StudyDashboard {
    
        private final int totalNumberOfEvents;
        public StudyDashboard() {
            this.totalNumberOfEvents = 15;
        }
    
    	... 
        
        private double getRate(Participant p) {
            ...
        }
    
        private String getMarkdownForParticipant(Participant p) {
            ...
        }
    
     }

    댓글

    Designed by JB FACTORY