이 글은 리팩터링 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로 많이 구성이 되어 있는데
실제로 코드들을 분석하다 보면 "왜" "무엇을" 하는지 구분하기 힘들다.
조건문, 반복문 쪼개기는 많이 연습해두자...

이 챕터는 다음 반복문 쪼개기 단계인
"반복문을 파이프라인으로 바꾸기"를 위함이다.

+ Recent posts