반복문 분리
레거시 코드를 보면 하나의 반복문에서 여러 다른 작업을 수행하는 코드를 쉽게 찾을 수 있습니다. 하지만, 그렇게 되면 반복문 안의 하나의 작업을 수정하는 데도 다른 작업까지 고려해야 하는 상황이 발생합니다.
반복문을 작업별로 분리하면 쉽게 이해하고 유지보수할 수 있습니다.
예시
아래의 예제는 두 가지 작업을 하고 있습니다. 그럼에도 이렇게 짜는 이유는 우리는 반복문의 범위가 동일하다면 굳이 분리하지 않기 때문입니다.
Date firstCreatedAt = null;
Participant first = null;
for (Comment comment: comments) {
Participant participant = findParticipant(comment.getUserName(), participants);
participant.setHomeworkDone(eventId);
if (firstCreatedAt == null || comment.getCreatedAt().before(firstCreatedAt)) {
firstCreatedAt = comment.getCreatedAt();
first = participant;
}
}
유지 보수성을 위해서 반복문을 분리해줍니다. 작업은 두 가지로 분리할 수 있습니다. (1. 댓글을 남긴 참가자에 한해 완료 처리 2. 댓글을 가장 빨리 남긴 참가자 1등 처리)
for (GHIssueComment comment: comments) {
Participant participant = findParticipant(comment.getUserName(), participants);
participant.setHomeworkDone(eventId);
}
Date firstCreatedAt = null;
Participant first = null;
for (GHIssueComment comment: comments) {
Participant participant = findParticipant(comment.getUserName(), participants);
if (firstCreatedAt == null || comment.getCreatedAt().before(firstCreatedAt)) {
firstCreatedAt = comment.getCreatedAt();
first = participant;
}
}
이제 책임이 조금 더 명확하게 되었습니다. 여기서 조금 더 읽기 쉬운 코드로 리팩토링하고자, 지난번에 포스팅했던 Extract method를 사용해서 각 loop문을 method로 추출합니다.
checkHomework(comments, eventId);
Participant first = findFirst(comments);
그러면 두 줄로 읽기 쉽고 책임이 명확하게 분리할 수 있습니다.
반복문을 분리하거나 반복문을 메서드로 추출하면 미세한 성능 저하가 발생할 수는 있습니다. 루프도 더 많이 돌고, 콜스택도 많아지기 때문입니다.
하지만, "리팩토링"은 "성능 최적화"라는 것과는 별개의 문제라고 합니다. 현재의 하드웨어 리소스 기준으로는 리팩토링이 끝난 후에 성능 최적화를 고민해야 맞는 것이라는 뜻이죠. 성능에 크리티컬하게 영향을 끼치는 리팩토링 기술이 아니라면요.
감사합니다.
출처 : 코딩으로 학습하는 리팩토링 - 인프런 백기선님 강의
'Programming > Refactoring' 카테고리의 다른 글
DTO를 Inner static class로 간결하게 관리하기! (+ domain 분리) (0) | 2022.04.16 |
---|---|
리팩토링 - Switch문을 다형성으로 바꾸기 (0) | 2022.02.27 |
리팩토링 - 메소드 올리기 (Pull up method) (0) | 2022.02.20 |
리팩토링 - 함수 추출 (Extract function) (0) | 2022.02.19 |
조건문 Refactoring 하는 방법! - 1편 (0) | 2022.02.07 |