본문 바로가기
JavaScript│Node js

마틴 파울러 [리팩토링] Refactoring - Javascript 1~22p 정리

by 자유코딩 2019. 6. 3.

리팩토링이란

코드의 중복을 제거하고 의도를 명확히 드러내는 것이다.

유지보수를 편리하게 만든다.

코드에 기능을 쉽게 추가할 수 있도록 한다.

 

리팩토링 하기 전 중요한 것

테스트 코드를 준비한다.

리팩토링 전,후 코드의 결과가 다르면 안된다.

 

리팩토링과 성능 튜닝의 상관 관계

성능 튜닝보다 리팩토링을 먼저한다.

지저분한 코드에 성능튜닝을 한다면 나중에 리팩토링 하면서 다시 코드가 바뀐다.

리팩토링을 먼저 하고 성능 튜닝을 하는 것이 작업을 두번 하지 않는 방법이다.

소개 된 리팩토링 방법

1. Extract Function ( Extract Method )

함수 추출하기

리팩토링 전

function MyFunction(a,b) {
    c = a + b;
    return (c * c);
}
result = MyFunction(4,6);
document.write(result);

---------------------------------------------------------------------------------------------------------------------

리팩토링 후

function extracted(a, b) {
    c = a + b;
}

function MyFunction(a,b) {
    extracted(a, b);
    return (c * c);
}
result = MyFunction(4,6);
document.write(result);

My function 이라는 함수 안에 c = a +b; 라는 부분이 있다.

a, b의 합을 계산하는 부분을 함수로 빼낸다.

그리고 MyFunction에서 extracted 를 호출한다.

 

let extracted = function () {
	c = a + b;
}; 
extracted();

 

function MyFunction(a,b) {
    function extracted() {
        c = a + b;
    }

    extracted();
    return (c * c);
}
result = MyFunction(4,6);
document.write(result);

 

---------------------------------------------------------------------------------------------------------------------

2.Split Loop

연속된 반복문을 분리한다.

// before
function statement(params) {
    let totalAmount = 0;
    let result = `Statement for {invoice.customer}`;
    let volumeCredits = 0;
    
    for (const perf of invoice.performance) {
        result += '.....';
        totalAmount += amountFor();
    }
    for (const perf of invoice.performance) {
        volumeCredits += volumeCreditsFor();
    }
    result += '';
    result += '';
    return result;
}

// after
function statement(params) {
    let totalAmount = 0;
    let result = `Statement for {invoice.customer}`;

    for (const perf of invoice.performance) {
        result += '.....';
        totalAmount += amountFor();
    }
    let volumeCredits = 0; // for 문 사이로 이동한다
    // 아래의 for문에서 사용하는데 굳이 위에 volumeCredits를 선언할 필요가 없다
    for (const perf of invoice.performance) {
        volumeCredits += volumeCreditsFor();
    }
    result += '';
    result += '';
    return result;
}

 

---------------------------------------------------------------------------------------------

3.Slide Statements 

// before
function statement(params) {
    let totalAmount = 0;
    let result = `Statement for {invoice.customer}`;
    let volumeCredits = 0;
    
    for (const perf of invoice.performance) {
        result += '.....';
        totalAmount += amountFor();
    }
    for (const perf of invoice.performance) {
        volumeCredits += volumeCreditsFor();
    }
    result += '';
    result += '';
    return result;
}

// after 1
function statement(params) {
    let totalAmount = 0;
    let result = `Statement for {invoice.customer}`;

    for (const perf of invoice.performance) {
        result += '.....';
        totalAmount += amountFor();
    }
    let volumeCredits = 0; // for 문 사이로 이동한다
    // 아래의 for문에서 사용하는데 굳이 위에 volumeCredits를 선언할 필요가 없다
    for (const perf of invoice.performance) { // after2에서 함수로 추출 될 부분
        volumeCredits += volumeCreditsFor();
    }
    result += '';
    result += '';
    return result;
}

// after 2
function totalVolumeCredits() { // volumeCredit 계산하는 부분을 함수로 추출 (Extract function)
    let volumeCredits = 0;
    for (const perf of invoice.performance) {
        volumeCredits += volumeCreditsFor(perf);
    }
    return volumeCredits;
}
function statement(invoice, plays) {
    let totalAmount = 0;
    let result = `Statement for {invoice.customer}`;

    for (const perf of invoice.performance) {
        result += '.....';
        totalAmount += amountFor();
    }
    let volumeCredits = totalVolumeCredits(); // 반복문을 함수로 추출
    result += '';
    result += '';
    return result;
}

// after 3
function totalVolumeCredits() {
    let volumeCredits = 0;
    for (const perf of invoice.performance) {
        volumeCredits += volumeCreditsFor(perf);
    }
    return volumeCredits;
}
function statement(invoice, plays) {
    let totalAmount = 0;
    let result = `Statement for {invoice.customer}`;

    for (const perf of invoice.performance) {
        result += '.....';
        totalAmount += amountFor();
    }    
    result += '';
    result += totalVolumeCredits(); // 변수 선언 제거 inline variable
    return result;
}

 

------------------------------------------------------------------------------------------

4.Inline variable

변수 제거하기

리팩토링 전

string 이라는 변수가 선언되어 있다

Parenizor.method('toString', function () {
    var string = '(' + this.getValue() + ')';
    return string;
}

------------------------------------------------------------------------------------------------------------

리팩토링 후

변수 string이 제거되었다. 임시로 선언한 변수는 제거한다.

Replace with query 방법.

Parenizor.method('toString', function () {
    return '(' + this.getValue() + ')';
}

 

 

리팩토링 공부에 도움되는 사이트

1.java

https://www.jetbrains.com/help/idea/change-signature.html

2.javascript

https://www.jetbrains.com/help/webstorm/specific-javascript-refactorings.html#javascript_extract_method

3.python

https://www.jetbrains.com/help/pycharm/inline.html

 

 

댓글