Notice
Recent Posts
Recent Comments
Link
관리 메뉴

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

[Refactoring] 11-4 상속 리펙토링 (Wrapper 만들기) 본문

Refactoring (리펙토링)

[Refactoring] 11-4 상속 리펙토링 (Wrapper 만들기)

jake-kim 2023. 7. 28. 22:16

상속 관계를 제거하고 Wrapper 만들기

  • 상속의 단점 (이전 포스팅 글에서 알아본 내용 복습)
    • 단점1) 수퍼클래스와 서브클래스간의 결합도가 증가하여 부모를 수정하면 자식들의 기능을 헤칠 수 있음
    • 단점2) 사람 객체의 동작이 나이대와 소득 수준으로 나뉜다면, 서브클래스를 부자와 서민으로 나눌 것인데 이렇게 된다면 각 서브클래스에서 하나의 인스턴스로 두 기능 모두 사용이 불가능한 상태
  • 상속을 제거하려는 목적이 있고 새로운 기능이 별로 추가되지 않을 때 wrapper 모델을 만들고 여기에 추가 기능 확장을 하는 방식

ex) Person 이라는 모델이 있고 여기에 사람에 대한 정보가 있을 때, User라는 모델을 만들고 싶은 경우?

struct Person {
    let name: String
    let age: Int
    
    var isNameUnique: Bool {
        Bool.random()
    }
    
    func old(than otherAge: Int) -> Bool {
        age < otherAge
    }
}
  • Person을 property로 가지고 있는 User 모델을 생성
    • User모델에는 새로운 id 프로퍼티와 getPassword() 메소드가 존재
struct User {
    let id = UUID().uuidString
    let person: Person
    
    func getPassword() -> String {
        "\(id) \(person.name)"
    }
}
  • 사용하는 쪽에서는 Person이 wrapping 되었으므로 person 프로퍼티나 기능을 사용하려면 .person으로 접근하는 번거로움이 존재
let user = User(person: .init(name: "jake", age: 20))
let isUnique = user.person.isNameUnique
let name = user.person.name
  • 핵심 - extension으로 인터페이스 뚫어주기
    • User에 extension을 이용하여 인터페이스만 뚫어지면 쉽게 접근이 가능
extension User {
    init(name: String, age: Int) {
        self.person = .init(name: name, age: age)
    }
    
    var isNameUnique: Bool {
        person.isNameUnique
    }
    
    var name: String {
        person.name
    }
}

사용하는쪽)

let user2 = User(name: "jake", age: 20)
let isUnique2 = user2.person
let name2 = user2.name

(extension으로 인터페이스 뚫기 전의 코드)

  • 불필요하게 person 프로퍼티를 거쳐가는 방식이므로 extension으로 인터페이스를 뚫어주는게 핵심
let user1 = User(person: .init(name: "jake", age: 20))
let isUnique = user1.person.isNameUnique
let name = user1.person.name



* 전체 코드: https://github.com/JK0369/ExRefactor11_4/tree/main/ExRefactor12_1

Comments