1. 알고자 하는 것
- 메서드를 추출할 때(Extract method), 해당 메서드에 넘겨야 하는 매개변수가 많아질 경우의 리팩토링
1. 임시 변수를 질의 함수로 바꾸기 (Replace Temp with Query)
2. 매개변수 객체 만들기 (Introduce Parameter Object)
3. 객체 통째로 넘기기 (Preserve Whole Object)
2. 알게된 것
임시 변수를 질의 함수로 바꾸기 (Replace Temp with Query)
- 긴 메서드를 메서드 추출을 통해 리팩토링 할 때, 임시 변수를 메서드로 추출하여 분리함으로써 매개변수의 개수를 줄인다.
try (FileWriter fileWriter = new FileWriter("participants.md");
PrintWriter writer = new PrintWriter(fileWriter)) {
participants.sort(Comparator.comparing(Participant::username));
writer.print(header(totalNumberOfEvents, participants.size()));
participants.forEach(p -> {
long count = p.homework().values().stream()
.filter(v -> v == true)
.count();
double rate = count * 100 / totalNumberOfEvents;
// 메서드로 추출하고자 하는 코드
String markdownForHomework = String.format("| %s %s | %.2f%% |\n", p.username(), checkMark(p, totalNumberOfEvents), rate);
writer.print(markdownForHomework);
});
}
- 위 각 issue 참여자에 대해 Markdown String을 만드는 메서드를 추출한다.
try (FileWriter fileWriter = new FileWriter("participants.md");
PrintWriter writer = new PrintWriter(fileWriter)) {
participants.sort(Comparator.comparing(Participant::username));
writer.print(header(totalNumberOfEvents, participants.size()));
participants.forEach(p -> {
long count = p.homework().values().stream()
.filter(v -> v == true)
.count();
double rate = count * 100 / totalNumberOfEvents;
// 메서드 추출
String markdownForHomework = getMarkdownForParticipants(totalNumberOfEvents, p, rate);
writer.print(markdownForHomework);
});
}
// 메서드 추출
private String getMarkdownForParticipants(int totalNumberOfEvents, Participant p, double rate) {
return String.format("| %s %s | %.2f%% |\n", p.username(), checkMark(p, totalNumberOfEvents), rate);
}
- 코드는 한결 깔끔해졌으나, 추출한 메서드의 매개변수가 3개로 많아지는 문제가 발생한다.
- 이 중, 매개변수로 넘어가는 rate 변수는 위 forEach block에서 따로 계산하는 코드가 존재한다.
- 해당 rate 변수를 계산하는 코드 역시 메서드로 추출하는 과정을 거친다.
- 추출한 rate 변수를 계산하는 메서드를 getMarkdownForParticipants 메서드 내에서 호출한다.
try (FileWriter fileWriter = new FileWriter("participants.md");
PrintWriter writer = new PrintWriter(fileWriter)) {
participants.sort(Comparator.comparing(Participant::username));
writer.print(header(totalNumberOfEvents, participants.size()));
participants.forEach(p -> {
// 매개변수가 2개로 감소
String markdownForHomework = getMarkdownForParticipants(totalNumberOfEvents, p);
writer.print(markdownForHomework);
});
}
// rate를 계산하는 메서드 추출
private static double getRate(int totalNumberOfEvents, Participant p) {
long count = p.homework().values().stream()
.filter(v -> v == true)
.count();
double rate = count * 100 / totalNumberOfEvents;
return rate;
}
private String getMarkdownForParticipants(int totalNumberOfEvents, Participant p) {
// 해당 메서드 내에 getRate 메서드를 호출
return String.format("| %s %s | %.2f%% |\n", p.username(), checkMark(p, totalNumberOfEvents), getRate(totalNumberOfEvents, p));
}
- 결과적으로 getMarkdownForParticipants 메서드의 매개변수를 1개 줄일 수 있다.
3. 정리
- 메서드를 추출할 때(Extract method), 해당 메서드에 넘겨야 하는 매개변수가 많아질 경우의 리팩토링 방법은 크게 3가지가 있다.
- 그 중 하나는, 임시 변수를 질의 함수로 바꾸기 (Replace Temp with Query) 이다.
- 이는 매개변수에 임시 변수가 포함된다면 이 역시도 메서드로 추출하여 분리함으로써 매개변수의 개수를 줄이는 방법이다.
Reference
'Clean Code' 카테고리의 다른 글
Java 리팩토링 - 조건문 분해하기 (0) | 2023.10.31 |
---|---|
Java 리팩토링 - 함수를 명령(Command)으로 바꾸기 (0) | 2023.10.06 |
Java 리팩토링 - 메서드 추출 시 매개변수가 많아질 경우 [3. 객체 통째로 넘기기] (0) | 2023.09.26 |
Java 리팩토링 - 메서드 추출 시 매개변수가 많아질 경우 [2. 매개변수 객체 만들기] (0) | 2023.06.20 |
Java 리팩토링 - 짧은 메서드 vs 긴 메서드 & Extract Method (0) | 2023.06.20 |