Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[Refactoring] 9-3 조건부 로직 최소화 (중첩 조건문을 보호 구문으로 바꾸기, swift에서 guard문의 의미) 본문

Refactoring (리펙토링)

[Refactoring] 9-3 조건부 로직 최소화 (중첩 조건문을 보호 구문으로 바꾸기, swift에서 guard문의 의미)

jake-kim 2023. 6. 2. 01:06

중첩 조건문을 보호 구문으로 바꾸기

  • 중첩 조건문이 많이 들어있는 케이스는 코딩을 하다보면 흔하게 발생하는데, 중첩이 되는 순간 깊이가 깊어지면서 읽기가 어려운 코드가 됨
  • if와 else 구문이 있을 때, if절과 else절은 똑같은 무게를 두어서 코드를 읽는 이에게 양 갈래가 똑같이 중요하다는 암시적인 의미를 전달하는데, 짧은 중첩 조건문이 있을땐 보호 구문으로 바꾸는게 좋음

중첩 조건문을 보호 구문으로 바꾸기

  • swift의 guard와 같은 보호 구문으로 변경하면, 이건 이 함수의 핵심이 아니고, 이 일이 일어나면 무언가 조치를 취한 후 함수에서 빠져나온다는 의미를 전달예제
    • swift에만 있는 guard문 키워드가 탄생한 이유
    • 보호구문 리펙토링의 핵심은 함수 내부의 의도를 부각하는 것

중첩 조건문을 보호구문으로 변경하기 예제

  • 리펙토링 전)
    • 실제로 벌어지는 중요한 일들이 중첩된 조건들에 의해 잘 보이지 않음
    • 중요하지 않은 조건문은 보호구문으로 변경함으로써 함수 내부의 의도를 부각시키는것이 필요
// refactor 전
func getPayment() -> UInt {
    if isFinished {
        return 0
    } else {
        if isRetired {
            return 1
        } else {
            if isPaymented {
                return 2
            } else {
                return getCalculatedPayment()
            }
        }
    }
}
  • 보호구문으로 변경
    • 중첩된 분기문은 무조건 보호구문으로 만들 수 있다는 것을 알고, 보호구문으로 리펙토링
// refactor 후 1
func getPayment_refactor1() -> UInt {
    if isFinished {
        return 0
    }
    if isRetired {
        return 1
    }
    if isPaymented {
        return 2
    }
    return getCalculatedPayment()
}
  • swift에서는 guard문이 있으므로 guard 키워드로 사용하면 더욱 깔끔하게 리펙토링이 가능
    • 핵심적이지 않은 조건들을 보호구문으로 바꾸니까, 함수 내부의 의도를 부각
// refactor 후 2
func getPayment_refactor2() -> UInt {
    guard !isFinished else { return 0 }
    guard !isRetired else { return 1 }
    guard !isPaymented else { return 2 }
    return getCalculatedPayment()
}

정리

  • 중첩된 조건문들은 반드시 보호구문으로 리펙토링이 가능
  • 보호구문을 사용하면 함수 관점으로 이건 이 함수의 핵심이 아니고, 이 일이 일어나면 무언가 조치를 취한 후 함수에서 빠져나온다는 의미를 나타내며 함수 의도가 부각됨
  • 리펙토링할때 swift의 guard 키워드를 사용하면 금상첨화

* 전체 코드: https://github.com/JK0369/ExRefactoring9_3

* 참고

- Refactoring (Martin Flowler)

Comments