Code Refactoring (코드 리팩터링)

Technique

Language :

리팩터링은 겉으로 드러나는 코드의 기능은 바꾸지 않으면서 내부 구조를 개선하는 방식으로 소프트웨어 시스템을 수정하는 과정이다. 요컨대, 리팩터링한다는 것은 코드를 작성하고 난 뒤에 설계를 개선하는 일이다.

마틴 파울러

리팩터링 (Refactoring)

소프트웨어 공학에서 '결과의 변경 없이 코드의 구조를 재조정함'을 뜻한다.

리팩터링을 할 때는 기능을 추가하지 않는다.

때로는 리팩터링보다 코드를 새로 작성하는 것이 쉬울 때도 있다.

목적

코드의 품질을 향상시키고 소프트웨어 개발 및 유지 보수를 효율적으로 만들기 위해 다음 목적을 가지고 수행한다.

가독성 향상

  • 소프트웨어를 이해하기 쉬워진다.
  • 개발자들간에 협업하기 용이해진다.

유지보수성 향상

  • 유지보수하는 과정이 간단해진다.
  • 코드 중복을 제거하여 잠재적인 버그를 감소시킬 수 있다.
  • 구조화와 모듈화를 통해 새로운 기능을 추가하거나 버그를 수정하는 작업이 더 쉬워진다

언제

코드 리뷰: 동료 개발자들과 코드를 검토하면서 품질을 높이고 개선할 수 있다.

기능 추가 직전: 기존 코드에 새로운 기능을 추가하기 쉽게 기존 코드를 리팩터링할 수 있다.

버그 수정: 버그를 수정하는 과정에서 리팩터링을 수행하여 버그를 더 쉽게 이해하고 해결할 수 있다.

정기적인 유지보수: 주기적으로 코드를 개선하고 최적화한다.

방법

하드 코딩된 숫자는 상수로 대체하기

kotlin

if (temperature > 100) { // boiling point
    // Do something if temperature is above boiling
}

kotlin

val BOILING_POINT = 100
if (temperature > BOILING_POINT) {
     // Do something if temperature is above boiling
}

중복된 코드 제거하기

kotlin

fun process(user: User) {
    if (user.status == UserStatus.SPROUT) {
        println("======= ## ${user.status} ## =======")
        // ...
    } else if (user.status == UserStatus.ROSE) {
        println("======= && ${user.status} && =======")
        // ...
    } else if (user.status == UserStatus.TREE) {
        println("======= @@ ${user.status} @@ =======")
        // ...
    }
}

kotlin

fun process(user: User) {
    if (user.status == UserStatus.SPROUT) {
        printStatus(user.status, "#")
        // ...
    } else if (user.status == UserStatus.ROSE) {
        printStatus(user.status, "&")
        // ...
    } else if (user.status == UserStatus.TREE) {
        printStatus(user.status, "@")
        // ...
    }
}

private fun printStatus(status: UserStatus, decorate: String) {
    println("======= $decorate$decorate $status $decorate$decorate =======")
}

간단한 조건문은 삼항 연산자처럼 사용하기 (Kotlin은 삼항 연산자가 없다)

kotlin

var text: String
if (zipCode != null) {
    text = "$zipCode) $address"
} else {
    text = address
}

kotlin

val text = if (zipCode != null) "$zipCode) $address" else address

kotlin

val text = zipCode?.let { "$zipCode) $address" } ?: address

조건이 여러 개인 조건문에 경우 when이 나을 때도 있다.

kotlin

val agePeriod = if (age >= 65) "노년기"
else if (age >= 45) "장년기"
else if (age >= 30) "중년기"
else if (age >= 19) "청년기"
else if (age >= 7) "소년기"
else "유년기"

kotlin

val agePeriod = when {
    age >= 65 -> "노년기"
    age >= 45 -> "장년기"
    age >= 30 -> "중년기"
    age >= 19 -> "청년기"
    age >= 7 -> "소년기"
    else -> "유년기"
}

긴 메서드 분리하기

kotlin

fun process() {
    // 유효성 검사에 대한 로직
    // ...
    // 계산에 대한 로직
    // ...
    // 상태 변경에 대한 로직
    // ...
}

kotlin

fun process() {
    validation()
    caluration()
    changeState()
}

fun validation() {
    // 유효성 검사에 대한 로직
}
fun caluration() {
    // 계산에 대한 로직
}
fun changeState() {
    // 상태 변경에 대한 로직
}

의미 있는 이름 사용하기 (변수명, 메서드명 등등)

kotlin

fun process(num: Int): Boolean {
    return if (num % 4 == 0) !(num % 400 != 0 && num % 100 == 0) else false
}

kotlin

fun checkLeapYear(year: Int): Boolean {
    return if (year % 4 == 0) !(year % 400 != 0 && year % 100 == 0) else false
}

https://www.techtarget.com/searchapparchitecture/definition/refactoring

https://dev.to/documatic/5-code-refactoring-techniques-to-improve-your-code-2lia

https://woogong80.tistory.com/213#google_vignette

https://velog.io/@rlrhs11/Code-Refactoring코드-리펙토링-이란

https://ikkison.tistory.com/82

https://jeongkyun-it.tistory.com/66

https://dmdwn3979.tistory.com/13

https://2minmin2.tistory.com/72

https://taes-k.github.io/2-where-when-refactoring.html

민갤

Back-End Developer

백엔드 개발자입니다.