본문 바로가기
독서/리팩터링

[리팩터링] 챕터06. 기본적인 리팩터링(6 - 2 함수 인라인하기)

by 공부하는개미 2022. 5. 28.

 

😀 책에서 기억하고 싶은 내용을 써보세요.

리팩터링 전

function getRating(driver) {
	return moreThanFiveLateDeliveries(driver) ? 2 : 1;
}

function moreThanFileLateDeliveries(driver) {
	return driver.numberOfLateDeliveries > 5;
}

 

리팩터링 후

function getRating(driver) {
	return (driver.numberOfLateDeliveries > 5) ? 2 : 1;
}

 

 

배경

  • 이 책은 분명히 드러나는 이름의 짤막한 함수를 이용하기를 권한다.
    • 그래야 코드가 명료해지고 이해하기 쉬워지기 때문이다.
    • 하지만 함수 본문이 이름만큼 명확한 경우도 있다. 또는 함수 본문 코드를 이름만큼 깔끔하게 리팩터링할 때도 있다. ⇒ 이럴 때는 그 함수를 제거한다.
    • 간접 호출은 유용할 수도 있지만 쓸데없는 간접 호출은 거슬릴 뿐이다.
  • 리팩터링 과정에서 잘못 추출된 함수들도 다시 인라인한다.
    • 잘못 추출된 함수들을 원래 함수로 합친 다음, 필요하면 원하는 형태로 다시 추출
  • 간접 호출을 너무 과하게 쓰는 코드도 흔한 인라인 대상이다.
    • 가령 다른 함수로 단순히 위임하기만 하는 함수들이 너무 많아서 위임 관계가 복잡하게 얽혀 있으면 인라인해버린다.

 

절차

  1. 다형 메서드(polymorphic method)인지 확인한다. ⇒ 서브클래스에서 오버라이드하는 메서드는 인라인하면 안 된다.
  2. 인라인할 함수를 호출하는 곳을 모두 찾는다.
  3. 각 호출문을 함수 본문으로 교체한다.
  4. 하나씩 교체할 때마다 테스트한다. ⇒ 인라인 작업을 한 번에 처리할 필요는 없다. 인라인하기가 까다로운 부분이 있다면 일단 남겨두고 여유가 생길 때마다 틈틈이 처리한다.
  5. 함수 정의(원래 함수)를 삭제한다.

 

 

예시

function rating(aDriver) {
	return moreThanFiveLateDeliveries(aDriver) ? 2 : 1;
}

function moreThanFiveLateDeliveries(aDriver) {
	return aDriver.numberOfLateDeliveries > 5;
}

호출되는 함수의 반환문을 그대로 복사해서 호출하는 함수의 호출문을 덮어쓰면 끝이다.

리팩터링 후

function rating(aDriver) {
	return aDriver.numberOfLateDeliveries > 5 ? 2 : 1;
}

 

 

예시2

function reportLines(aCustomer) {
	const lines = [];
	gatherCustomerData(lines, aCustomer);
	return lines;
}

function gatherCustomerData(out, aCustomer) {
	out.push(["name", aCustomer.name]);
	out.push(["location", aCustomer.location]);
}
  • 단순히 잘라 붙이는 식으로는 gatherCustomerData()를 reportLines()로 인라인할 수 없다.
  • 먼저 여러 문장을 호출한 곳으로 옮기기를 적용해서 첫 문장부터 시작해보자.

 

function reportLines(aCustomer) {
	const lines = [];
	lines.push(["name", aCustomer.name]);
	gatherCustomerData(lines, aCustomer);
	return lines;
}

function gatherCustomerData(out, aCustomer) {
	~~out.push(["name", aCustomer.name]);~~
	out.push(["location", aCustomer.location]);
}

나머지 문장도 같은 식으로 처리한다.

 

function reportLines(aCustomer) {
	const lines = [];
	lines.push(["name", aCustomer.name]);
	lines.push(["location"], aCustomer.location]);
	return lines;
}
  • 여기서 핵심은 항상 단계를 잘게 나눠서 처리하는 데 있다.
  • 평소 저자의 스타일대로 함수를 작게 만들어뒀다면 인라인을 단번에 처리할 수 있을 때가 많다. 그러다 상황이 복잡해지면 다시 한 번에 한 문장씩 처리한다.
  • 한 문장을 처리하는 데도 얼마든지 복잡해질 수 있다. ⇒ 이럴 때는 더 정교한 리팩터링인 문장을 호출한 곳으로 옮기기로 작업을 더 잘게 나눈다.

 

🤔 오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요.

  • 상황에 맞게 잘게 나누거나 한 문장씩 처리할 수도 있다는 것을 알게 되었습니다.
    • 여기서 한 문장씩 처리하는 과정을 거칠 때 전 단계에서 잘게 나눠져 있어야 처리가 편하다.

 

🔎 궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.

  • 다형 메서드란?
    • 다형성을 개념을 보면 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미합니다.
    • 자바에서 이러한 다형성을 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여 구현하고 있습니다.
    • 다형성은 상속, 추상화와 더불어 객체 지향 프로그래밍을 구성하는 중요한 특징 중 하나입니다.
    • 다형성을 활용하면 기능을 확장하거나, 객체를 변경해야할 때 타입 변경 없이 객체 주입만으로 수정이 일어나게 할 수 있다
    • 상속을 사용한다면 중복되는 코드까지 제거할 수 있으므로 더욱 객체 지향 설계와 가까워질 수 있다.

 

 

반응형