상세 컨텐츠

본문 제목

코드 리팩토링(Code Refactoring)

Information Technology/Computer Science

by Developer, Jiyong Kim 2024. 5. 1. 10:58

본문

코드리팩토링은 마치 케이블 정리와 같다

 

코드 리팩토링이란 코드의 중복을 지우고, 로직을 깨끗하고 이해하기 쉽게 재구성하는 것을 말한다.  리팩토링의 판단 기준은 확장성, 가동성, 유지보수성이 있으며, 이는 종종 코드 최적화, 디버깅, 방어 코드 추가와 같은 행위와 혼동될 수 있다.

 

리팩토링은 당연하게도 중간에 하는 작업이 아니라 코드 작성을 마친 후에 진행되어야 한다. 기능 구현이 우선이고, 정상 작동되는지 확인한 후에 리팩토링을 진행한다. 리팩토링을 할 때에는 한 번에 하나의 작업에만 집중하고, 동시에 여러 작업을 진행하지 않는다. 물론 리팩토링을 하면서 지속적으로 코드가 정상적으로 동작하는지 확인해야 하고, 리팩토링 작업이 동작에 영향을 주어서는 안된다.

 

리팩토링은 크게 두 가지로 나뉜다. 하나는 신규 기능 추가를 대비한 "준비를 위한 리팩토링", 또 하나는 높은 가독성을 고려한 "이해를 위한 리팩토링"이다. 각각에 대한 자세한 내용은 아래에서 예제와 함께 살펴보도록 하자.

 

우선 준비를 위한 리팩토링은 신규 기능을 추가하기 전에 코드를 쉽게 추가할 수 있도록 대비하는 것이 목적이다.

 

예제1) 파편화된 코드 리팩토링: 동일 코드의 반복을 별도의 Function으로 만들어 이를 호출하는 방식으로 분리

// 리팩토링 전
function printOwing(invoice) {
  printBanner();
  let outstanding = calculateOutstanding();
  
  // print details
  console.log(`name: ${invoice.customer}`);
  console.log(`amount: ${outstanding}`);
}

// 리팩토링 후
function printOwing(invoice) {
  printBanner();
  let outstanding = calculateOutstanding();
  printDetails(outstanding);
  
  function printDetails(outstanding) {
    console.log(`name: ${invoice.customer}`);
    console.log(`amount: ${outstanding}`);
  }
}

 

예제2) 중복된 유사 로직: 의미가 유사한 function을 매개 변수를 이용하여 통합(추가적인 소스 수정 및 배포 불필요)

// 리팩토링 전
function tenPercnetRaise(aPerson) {
  aPerson.salary = aPerson.salary.multiply(1.1);
}

function fivePercentRaise(aPerson) {
  aPerson.salary = aPerson.salary.multiply(1.05);
}

// 리팩토링 후
function raise(aPerson, factor) {
  aPerson.salary = aPerson.salary.multiply(1 + factor);
}

 

예제3) 모든 분기마다 동일 로직: 모든 분기마다 동일 로직이 있다면 이를 분기문 밖으로 이동시켜 한 번만 작성

// 리팩토링 전
if (isSpecialDeal()) {
  total = price * 0.95;
  send();
}
else {
  total = price * 0.98;
  send();
}

// 리팩토링 후
if (isSpecialDeal()) {
  total = price * 0.95;
}
else {
  total = price * 0.98;
}
send();

 

다음으로 이해를 위한 리팩토링은 코드의 의도를 쉽고 명확하게 이해할 수 있도록 가독성을 높이는 것이 목적이다.

 

예제1) 모호한 변수명: 의도를 알 수 없는 모호한 변수명을 직관적으로 선언

// 리팩토링 전
let a = height * width;

// 리팩토링 후
let area = height * width;

 

예제2) 길어지는 표현식: 표현식이 너무 길어지면, 이를 의도 파악이 가능한 개별 변수로 선언

(소스코드가 길어졌으나 가독성이 눈에 띄게 향상되었다. 코드의 길이와 가독성이 항상 반비례하지는 않는다.)

// 리팩토링 전
return order.quantity * order.itemPrice - 
  Math.max(0, order.quantity - 500) * order.itemPrice * 0.05 + 
  Math.min(order.quantity * order.itemPrice * 0.1, 100);

// 리팩토링 후
const basePrice = order.quantity * order.itemPrice;
const quantityDiscount = Math.max(0, order.quantity - 500) * order.itemPrice * 0.05;
const shipping = Math.min(order.quantity * order.itemPrice * 0.1, 100);
return basePrice - quantityDiscount - shipping;

 

예제3) 변수가 한 번만 변경: 변경되는 변수가 하나이고, 변경이 한 번 뿐이라면 변수 선언 대신 Inline으로 처리

// 리팩토링 전
let basePrice = anOrder.basePrice;
return (basePrice > 1000);

// 리팩토링 후
return anOrder.basePrice > 1000;

 

여기까지 코드 리팩토링에 대해 알아보았다. 코드 판독 자체가 불가하거나 정상 작동 하지 않는 코드라면 리팩토링 할바에 그냥 새로 짜는 것이 낫다. 그럼 20000

관련글 더보기