👀 중복코드의 단점
1. 비슷한 코드인지, 완전히 동일한 코드인지 주의깊게 살펴봐야 한다.
2. 코드 변경 시 통일한 모든 곳의 코드를 변경해야 한다.
✍ 사용할 수 있는 리팩토링 기술
1. 함수 추출하기
- 동일한 코드를 여러 메소드에서 사용하는 경우 사용한다.
- 무슨 일을 하는 코드인지 알아내려고 노력해야 하는 코드라면,
해당 코드를 함수로 분리하고
함수 이름으로 "무슨 일을 하는지" 표현할 수 있다. ( = 의도를 드러낼 수 있다. )
[ Berfore ]
* printParticipants()
: 깃헙 커넥션을 만들고 -> 리포지토리를 읽어오고 -> 이슈를 찾아서 -> 이슈에서 코멘트를 돌면서
-> 참석한 사람들의 이름을 담아주고 -> 담은 userName을 출력하는 내용이다.
import org.kohsuke.github.GHIssue;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
public class StudyDashboard {
private void printParticipants(int eventId) throws IOException {
// Get github issue to check homework
GitHub gitHub = GitHub.connect();
GHRepository repository = gitHub.getRepository("whiteship/live-study");
GHIssue issue = repository.getIssue(eventId);
// Get participants
Set<String> participants = new HashSet<>();
issue.getComments().forEach(c -> participants.add(c.getUserName()));
// Print participants
participants.forEach(System.out::println);
}
private void printReviewers() throws IOException {
// Get github issue to check homework
GitHub gitHub = GitHub.connect();
GHRepository repository = gitHub.getRepository("whiteship/live-study");
GHIssue issue = repository.getIssue(30);
// Get reviewers
Set<String> reviewers = new HashSet<>();
issue.getComments().forEach(c -> reviewers.add(c.getUserName()));
// Print reviewers
reviewers.forEach(System.out::println);
}
public static void main(String[] args) throws IOException {
StudyDashboard studyDashboard = new StudyDashboard();
studyDashboard.printReviewers();
studyDashboard.printParticipants(15);
}
}
[ After ]
- 인텔리제이 기준으로 Refractor -> extract method 기능을 활용하여
중복되는 코드들을 메소드로 추출하였다.
또한 메소드 이름으로 해당 코드가 무슨 일을 하는지 명시하였기 때문에 주석을 없앴다.
(ex) getGhIssue(), getUserNames(), print()
2. 코드 정리하기 (slide Statements)
- 관련있는 코드끼리 묶여있어야 코드를 더 쉽게 이해할 수 있다.
- 함수에서 사용할 변수를 미리 상단에 정의하기보다,
해당 변수를 사용하는 코드 바로 위에 선언하자.
- 관련있는 코드끼리 묶은 다음 함수추출하기를 사용해 더 깔끔하게 분리할 수도 있다.
[ 예시 ]
아래 빨간 박스처럼 위에 변수를 미리 다 선언하면
- 관련된 코드를 한 뭉치로 보기 어렵고
- 이게 어디 선언됐었지? 하고 다시 위를 올려다 보는 경우가 발생할 수 있고
- 중복되는 코드인지 헷갈릴 수도 있다.
3. 메소드 올리기 (Pull Up Method)
- 상속구조에서 발생할 수 있으며, 하위클래스에서 상위클래스로 중복된 메소드를 올리는 방법이다.
- 비슷하지만 일부 값만 다른 경우라면,
"함수 매개변수화하기" 리팩토링을 적용한 이후에 이 방법을 사용할 수 있다.
- 하위 클래스에 있는 코드가 상위클래스가 아닌
하위클래스 기능에 의존하고 있다면
"필드 올리기"를 적용한 이후에 이 방법을 적용할 수 있다.
- 두 메소드가 비슷한 절차를 따르고 있다면,
"템플릿 메소드 패턴" 적용을 고려할 수 있다.
[ Berfore ]
- 각 자식 클래스에서 printUsernames 함수는 비슷한 동작을 수행하는 중복 코드이다.
- 자식 클래스에서의 반복되는 중복 코드의 수정은 일괄 수정이 어렵다.
import java.io.IOException;
public class Dashboard {
public static void main(String[] args) throws IOException {
ReviewerDashboard reviewerDashboard = new ReviewerDashboard();
reviewerDashboard.printReviewers();
ParticipantDashboard participantDashboard = new ParticipantDashboard();
participantDashboard.printParticipants(15);
}
}
import org.kohsuke.github.GHIssue;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
public class ParticipantDashboard extends Dashboard {
public void printParticipants(int eventId) throws IOException {
// Get github issue to check homework
GitHub gitHub = GitHub.connect();
GHRepository repository = gitHub.getRepository("whiteship/live-study");
GHIssue issue = repository.getIssue(eventId);
// Get participants
Set<String> participants = new HashSet<>();
issue.getComments().forEach(c -> participants.add(c.getUserName()));
// Print participants
participants.forEach(System.out::println);
}
}
import org.kohsuke.github.GHIssue;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
public class ReviewerDashboard extends Dashboard {
public void printReviewers() throws IOException {
// Get github issue to check homework
Set<String> reviewers = new HashSet<>();
GitHub gitHub = GitHub.connect();
GHRepository repository = gitHub.getRepository("whiteship/live-study");
GHIssue issue = repository.getIssue(30);
// Get reviewers
issue.getComments().forEach(c -> reviewers.add(c.getUserName()));
// Print reviewers
reviewers.forEach(System.out::println);
}
}
[ After ]
인텔리제이의 Refactor -> Pull Members Up 기능을 통해
하위클래스의 동일한 부분을 메소드로 추출한 후 -> 상위클래스로 올린다.
출처 : 인프런 강의 (백기선 - 코딩으로 학습하는 리팩토링)
'Programming > 리팩토링' 카테고리의 다른 글
[리팩토링 기술-6] 단계 쪼개기 / 클래스 추출하기 (0) | 2022.11.10 |
---|---|
[리팩토링 기술-5] 반복문을 처리하는 리팩토링 (0) | 2022.11.08 |
[리팩토링 기술-4] 가변데이터를 처리하는 리팩토링 (0) | 2022.11.08 |
[리팩토링 기술-3] 긴 매개변수를 처리하는 리팩토링 (0) | 2022.11.08 |
[리팩토링 기술-2] 긴 함수를 처리하는 리팩토링 (0) | 2022.11.07 |