[Refactoring] 5-1.

리팩토링 코어

  • 각 방법의 “이유”를 인식하고 유연하게 적용

추출 기능

  • 함수를 사용하여 블록에서 무언가 빼기
    • 역 리팩토링: 인라인 함수


추출 기능

ex) 함수 추출 예시

  • 리팩토링 전
func printSome() {
    let person = Person()
    person.name = "jong"
    person.age = 20
    
    print("person's name: \(person.name)")
    print("person's age: \(person.age)")
}
  • 추출 기능은 리팩토링을 반영합니다.
func printSome() {
    let person = Person()
    person.name = "jong"
    person.age = 20
    
    print("person's name: \(person.name)")
    print("person's age: \(person.age)")
    printInfo(person: person)
}

func printInfo(person: Person) {
    print("person's name: \(person.name)")
    print("person's age: \(person.age)")
}
  • 특징 추출이 필요한 이유는 무엇입니까?
    • 일반적으로 함수의 코드가 길거나 복잡하거나 어려운 내용이 포함되어 있을 때 코드에 주석을 삽입하는데 이 방법이 아닌 함수로 따로 추출하여 주석을 함수 시그니쳐로 대체하여 코드를 작성할 수 있습니다. 코드를 읽을 때 더 빨리 읽을 수 있습니다.
  • 특징 추출을 잘하는 방법
    • “방법”이 아닌 “무엇”을 나타내도록 기능의 이름을 지정합니다.
    • 그러나 함수의 이름이 길어지지 않고 목적이 명확해진다. 짧은 함수 이름 선택만들다
    • 함수 추출에 많은 수의 매개변수가 필요한 경우 함수 추출을 중지하고 나중에 검토하십시오. 분할 변수임시 변수를 쿼리 함수로 전환그런 다음 기능을 추출하려고
  • 중첩 함수로 함수 추출
    • 중첩함수로 추출하면 내부함수에서 외부함수에서 선언한 지역변수에 접근할 수 있고, 매개변수를 따로 선언할 필요가 없어 오버엔지니어링을 줄일 수 있다는 장점이 있다.
    • 중첩 함수로 구현하면 해당 함수에서만 사용되므로 집계가 더 쉬워집니다.

ex) 위 예제에서 printInfo(person:) 는 별도의 person 파라미터 없이 중첩 함수로 구현할 수 있습니다.

func printSome() {
    let person = Person()
    person.name = "jong"
    person.age = 20
    
    printInfo()
    
    func printInfo() {
        print("person's name: \(person.name)")
        print("person's age: \(person.age)")
    }
}

함수 인라인

  • 코드를 명확하고 이해하기 쉽게 유지하려면 짧은 함수를 사용하는 것이 가장 좋지만 때로는 본문이 함수 이름보다 짧고 명확합니다.
  • 지나친 간접비는 때로 짜증이 나므로 이를 없애는 것이 목적


함수 인라인

예) 인라인 함수 예제 – 직무가 많은 직원에게 인센티브를 주는 코드

func printTotalSalary(person: Person) {
    print(getSalary(person: person))
}

func getSalary(person: Person) -> Int {
    moreThanThreeJobs(person: person) ? person.salary * 2 : person.salary
}

func moreThanThreeJobs(person: Person) -> Bool {
    person.jobs > 3
}
  • 별도의 moreThanThreeJobs 함수를 사용하는 대신 getSalary(person:) 메서드로 래핑합니다.
func getSalary(person: Person) -> Int {
    (person.jobs > 5) ? person.salary * 2 : person.salary
}
  • 함수를 인라인함으로써 getSalary 함수는 더 짧고 더 명확한 의미를 가지며 불필요한 간접 호출이 제거됩니다.

* 참조

– 리팩토링(Marting Flowler)