이 글은 리팩터링 2판(마틴 파울러) 책을 참고하였습니다.
순서
I. 배경
II. 절차
III. 예시
IV. 기타
I. 배경
종종 반복문 하나에서 두개 이상의 일을 수행한다.
그 이유는 필요한 루프가 같기 때문이다.
하지만 마틴 파울러는 하나의 반복문에서 하나의 작업만 수행하라고 한다.
그래야 사용하기 쉬워지고 실수할 가능성도 낮아진다.
불편해 할 수 있지만 리팩터링과 최적화는 구분해야한다.
최적화는 코드를 깔끔히 정리한 이후에 수행하자...
혹시, 반복문을 두 번 실행하는 것이 병목이라고 판단되면 그때 합치는건 쉽다.
(하지만 그럴 일이 매우 드물 것이라고 한다.)
II. 절차
1. 반복문을 복제해 두 개로 만든다.
2. 반복문이 중복되어 생기는 부수효과를 파악해서 제거한다.
3. 테스트한다.
4. 완료되었으면, 각 반복문을 함수로 추출할지 고민해본다.
III. 예시
원본 코드
#include "gtest/gtest.h"
class People {
public:
int age_;
int salary_;
};
People people[3] = {30, 5000, 40, 7000, 20, 3000};
void PrintYoungestAgeAndTotalSalary() {
int youngest = people[0].age_;
int total_salary = 0;
for (int i = 0; i < sizeof(people) / sizeof(People); ++i){
if (people[i].age_ < youngest) {
youngest = people[i].age_;
}
total_salary += people[i].salary_;
}
printf("%d, %d\n", youngest, total_salary);
}
TEST(SplitLoop, PrintYoungestAgeAndTotalSalary) {
PrintYoungestAgeAndTotalSalary();
}
1. 반복문을 복제하여 일을 나누기
// People 클래스, TEST구현 생략
#include "gtest/gtest.h"
class People;
People people[3] = {30, 5000, 40, 7000, 20, 3000};
// 수정해야 할 메인코드
void PrintYoungestAgeAndTotalSalary() {
int youngest = people[0].age_;
int total_salary = 0;
/* 1. For문 복제 후 작업 나누기(age)*/
for (int i = 0; i < sizeof(people) / sizeof(People); ++i) {
if (people[i].age_ < youngest) {
youngest = people[i].age_;
}
}
/* 1. For문 복제 후 작업 나누기(salary)*/
for (int i = 0; i < sizeof(people) / sizeof(People); ++i) {
total_salary += people[i].salary_;
}
printf("%d, %d\n", youngest, total_salary);
}
2. 나뉜 작업을 함수로 추출하기 (이름 명확히)
// People 클래스, TEST구현 생략
#include "gtest/gtest.h"
class People;
People people[3] = {30, 5000, 40, 7000, 20, 3000};
/* 2. 통째로 가져와서 함수로 만들기(age) */
int getYoungestAge() {
int youngest = people[0].age_;
for (int i = 0; i < sizeof(people) / sizeof(People); ++i) {
if (people[i].age_ < youngest) {
youngest = people[i].age_;
}
}
return youngest;
}
/* 2. 통째로 가져와서 함수로 만들기(salary) */
int getTotalSalary() {
int total_salary = 0;
int youngest = people[0].age_;
for (int i = 0; i < sizeof(people) / sizeof(People); ++i) {
total_salary += people[i].salary_;
}
return total_salary;
}
// 수정해야 할 메인코드
void PrintYoungestAgeAndTotalSalary() {
/* 2. 통째로 가져와서 함수로 만들기 */
/* 로컬 변수도 함수로 쪼개서 구현이 간단해짐 */
printf("%d, %d\n", getYoungestAge(), getTotalSalary());
}
IV. 기타
대부분의 알고리즘 코드가 If, For로 많이 구성이 되어 있는데
실제로 코드들을 분석하다 보면 "왜" "무엇을" 하는지 구분하기 힘들다.
조건문, 반복문 쪼개기는 많이 연습해두자...
이 챕터는 다음 반복문 쪼개기 단계인
"반복문을 파이프라인으로 바꾸기"를 위함이다.
'Programming > Refactoring(C++)' 카테고리의 다른 글
[Refactoring] 7. 객체 통째로 넘기기 (For Long Parameter) (2) | 2022.10.19 |
---|---|
[Refactoring] 6. 매개변수를 질의함수로 바꾸기 (For Long Parameter) (0) | 2022.10.18 |
[Refactoring] 4. 조건문 분해하기 (For Long Function Smell) (0) | 2022.10.17 |
[Refactoring] 3. 함수를 명령으로 바꾸기 (For Long Function Smell) (0) | 2022.10.17 |