Computer기본지식/리팩터링

리팩터링 Chapter 5, 6(앞부분) - 기본적인 리팩터링

HOONY_612 2021. 9. 10. 16:00
반응형

이번 장에서는 본격적으로 리팩터링기법에 대한 소개가 시작됩니다.

첫 번째 챕터는 함수추출과 인라인 등 기본적인 리팩터링 기술에 대해서 설명합니다.

양이 꽤 많은 관계로 반으로 나눠서 진행하였습니다.

 

Chapter 5. 리팩터링 카탈로그 보는 법

5-1 리팩터링 설명 형식

1. 개요

개념도 + 코드 예시가 나옵니다. 다음에 찾기 쉽게 기억 되살리기용 시각 장치입니다.

 

2. 절차

구체적인 진행 순서가 기억나지 않을 때 참고하는 것입니다.

작은 단계들을 밟아 나가는게 핵심입니다. 상황이 난해할수록 단계를 잘게 나누면됩니다.

 

3. 예시

레퍼런스로써 사용하면 됩니다. 물론 간단한 코드로 구성되어있습니다.

 

 

Chapter 6. 기본적인 리팩터링

6-1 함수 추출하기

function printOwing(invoice) {
	printBanner();
	let outstanding = calculateOutstanding();
}

console.log(`고객명: ${invoice.customer}`);
console.log(`채무액: ${outstanding}`);
function printOwing(invoice) {
	printBanner();
	let outstanding = calculateOutstanding();
	printDetails(outstanding);

	function printDetails(outstanding) {
		console.log(`고객명: ${invoice.customer}`);
		console.log(`채무액: ${outstanding}`);
	}
}

함수를 나누는 가장 명확한 기준은 "목적과 구현의 분리"하는 방식이 가장 적합합니다.

함수가 짧으면 짧을수록 캐싱하기가 더 쉽기 때문에 컴파일러가 최적화하는데 유리한 경우가 많습니다.

이 부분에 관하여 스터디에서 얘기가 나왔습니다.

자바를 예를 들면 .Java파일이 JVM Compiler에 의해서 Byte Code가 됩니다.

여기서 한번 더 컴파일을 하는데 그것을 JIT(Just in Time) Compiler라고 합니다.

JIT의 캐싱 기능을 이용합니다. 자주 사용하는 코드들을 미리 컴파일 해놓는 것입니다.  

 

함수 이름 정하기 주의사항

1. 목적을 잘 드러내는 이름을 붙입니다.(어떻게보다는 무엇을하는지 중심으로 드러내야합니다.)2.  추출한 코드 중 지역 변수참조나 유효범위를 벗어나는 변수가 없는지 검사합니다. 있다면 매개변수로 전달합니다.

 

⁉️ 값을 반환할 변수가 여러 개라면?

임시 변수 추출 작업과 임시 변수를 질의함수로 바꾸거나 변수를 쪼개는 방법으로 처리합니다.

 

 

6-2 함수 인라인하기

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

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

인라인 절차

다형 메서드인지 확인합니다.(오버라이드 메서드는 인라인하면 안됩니다.)

인라인할 함수를 호출하는 곳을 모두 찾습니다.

호출문들을 본문으로 교체합니다.

 

오버라이드 메서든느 왜 인라인 하면 안될까요?

답은 간단하다고 생각합니다. 오버라이드라는 것은 서브클래스에 선언하여 자기의 입맛대로 기능을 재구성하는 것입니다.

그러나 인라인을 하게되면 오버라이드를 할 수 없습니다.

물론 명확한 기능은 표현할 수 있어도 오버라이드 자체를 할 수 없습니다.

 

6-3 변수 추출하기

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(basePrice * 0.1, 100);
return basePrice - quantityDiscount + shipping;

복잡한 로직을 구성하는 단계마다 이름을 붙여 코드의 목적을 훨씬 명확하게 드러낼 수 있습니다.

위와 같이 변수를 지정해줄 수도 있지만 클래스를 이용하면 더 큰 장점을 얻을 수 있습니다.

class Order{
	constructor(aRecord) {
		this.data = aRecord;
	}

	get quantity() {return this._data.quantity;}
	get itemPrice() {return this._data.itemPrice;}
	get basePrice() {return this.quantity * this.itemPrice;}
..
...
}

위와 같이 데이터로 로직을 만들 경우 공유할 정보를 설명해주는 문맥이 되어줍니다.

 

6-4 변수 인라인하기

let basePrice = anOrder.basePrice;
return (basePrice > 1000);
return anOrder.basePrice > 1000;

 

6-5 함수 선언 바꾸기

function circum(radius) {...}
function circumference(radius) {...}

함수 선언 바꾸기는 두 가지 절차를 따릅니다. 함수 선언과 호출문들을 단번에 고칠 수 있으면 간단한 절차

아니면 마이그레이션 절차를 이용해야합니다.

 

간단한 절차

1. 매개변수를 제거하려든 먼저 함수 본문에서 제거 대상 매개변수를 참조하는 곳 확인.

2. 메서드 선언을 원하는 형태로 변경.

3. 기존 메서드 선언을 참조하는 부분을 모두 찾아서 바뀐 형태로 수정.

4. 테스트

 

마이그레이션 절차

1. 이어지는 추출 단계를 수월하게 만들어야 한다면 함수의 본문을 적절히 리팩터링.

2. 함수 본문을 새로운 함수로 추출.

3. 추출한 함수에 매개변수를 추가해야 한다면 '간단한 절차'이용

4. 테스트

5. 기존함수 인라인

6. 임시 이름을 원래이름으로 되돌림.

7. 테스트

 

 

저도 함수 선언 바꾸기는 이해가 잘 되지 않습니다.

위의 설명은 함수 이름 변경, 함수 매개변수 추가, 매개변수 속성바꾸기로 이해했습니다.

 

6-6 변수 캡슐화하기

let defaultOwner = {firstName: "마틴", lastName: "파울러"};
let defaultOwnerData = {firstName: "마틴", lastName: "파울러"};
export function defaultOwner() {return defaultOwnerData;}
export function setDefaultOwner(arg) {defaultOwnerData = arg;}

접근할 수 있는 범위가 넓은 데이터를 옮길 때는 먼저 그 데이터로의 접근을 독점하는 함수를 만드는

식으로 켭슐화하는 것이 가장 좋은 방법입니다. 데이터의 유효범위가 넓을수록 캡슐화해야합니다.

 

절차

캡슐화 함수를 만듭니다. 변수 참조하던 부분을 모두 캡슐화 함수 호출로 바꿉니다.

그리고 변수의 접근 범위를 제한합니다.

 

 

 

이번 장부터 본격적인 리팩터링 기술을 살펴봤습니다. 일단은 기본적인 리팩터링들이라서 조금 어렵지는 않은 것 같습니다.

나중에 뒤로 갈수록 많이 어려워지는 것 같습니다. 책의 내용이 저 같은 주니어들이 보기에 조금 까다롭게 되어있다고 느껴집니다.

왜냐하면 모든 내용에대해서 두루뭉실하게 이야기하는 부분이 대다수입니다.

그래서 지금 끝까지 읽어보고 향후 3년 뒤에 정독을 다시 해봐야겠다는 생각이듭니다.

반응형