관리 메뉴

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

[Refactoring] 11-1 상속 리펙토링 (메서드 올리기) 본문

Refactoring (리펙토링)

[Refactoring] 11-1 상속 리펙토링 (메서드 올리기)

jake-kim 2023. 7. 15. 01:47

메서드 올리기

  • 서브클래스들이 여러개 있을 때 이 클래스에서 동일한 내용을 정의하는 메서드가 있을 때 이 메서드를 수퍼클래스에 이동시켜서 중복을 제거할 수 있음
    • 중복의 위험) 동일한 로직을 사용하고 있는 중복 코드에서, 한쪽의 변경이 다른 쪽에는 반영이 안되는 이슈가 발생할 수 있는 가능성 존재

메서드 올리기

예시) 메서드 올리기

  • Member라는 수퍼 클래스가 있고 서브 클래스로 Developer, FireFighter가 존재
    • 얼핏보면 메서드 이름이 달라서 다른 메서드인것 같지만 같은 역할을 하는 것이므로 getFullname(), getName()을 하나로하여 수퍼 클래스로 이동이 필요
class Member {
    var age: Int
    var name: String
    
    init(age: Int, name: String) {
        self.age = age
        self.name = name
    }
    
    func sign() {
        print("sign")
    }
}

class Developer: Member {
    func getFullname() -> String {
        name
    }
}

class FireFighter: Member {
    func getName() -> String {
        name
    }
}
  • getName() 메서드를 올려서 코드 중복을 막은 상태
class Member {
    var age: Int
    var name: String
    
    init(age: Int, name: String) {
        self.age = age
        self.name = name
    }
    
    func sign() {
        print("sign")
    }
    
    func getName() -> String {
        name
    }
}

class Developer: Member {
}

class FireFighter: Member {
}

메서드 올리기 응용

  • 만약 아래처럼 Developer, FireFighter 클래스가 각각 있고 Member라는 수퍼클래스가 없을 때, 반대로 super class를 만들어서 상속 관계를 갇도록 리펙토링도 가능
class Developer {
    var age: Int
    var name: String
    
    init(age: Int, name: String) {
        self.age = age
        self.name = name
    }
}

class FireFighter {
    var age: Int
    var name: String
    
    init(age: Int, name: String) {
        self.age = age
        self.name = name
    }
}
  • 상속 리펙터링을 할 때 주의사항
    • 대표적으로 중복 코드를 제거하는 대표적인 2가지 방법은 상속 리펙터링과 protocol을 사용하는 방법이 있는데, 되도록이면 프로토콜을 사용하는것이 베스트 (이유는 이전 포스팅 글 참고)
  • 그럼 프로토콜을 지향해야하는데, 언제 상속을 사용하는지?
    • 누가봐도 상속 개념을 가지고 있는 것이고 명확하게 알 수 있는 것들에만 상속을 적용
    • ex) Shape 클래스를 수퍼 클래스로 놓고, 서브 클래스에서는 Circle, Rectangle과 같은 값으로 구현

 

* 참고

- Refactoring (Martin Flowler)

 

Comments