Swift) convenience init이란?

최근 앱을 개발하다 객체의 역할을 가져와 테스트를 해야하는 상황이 발생했습니다. 해당 객체는 전체 로직 중 일부로 원래대로면 해당 객체만 사용하는 일은 없었고 전체 플로우의 한 역할을 맡아서 수행하는 객체였습니다.
하지만 이 부분만 따로 테스트해야 할 필요가 있었고 어떻게 하면 기존 코드를 방해하지 않은 상태에서 객체를 생성해서 테스트를 해볼 수 있을까라는 고민을 했고 convenience init이 도움이 되었습니다.

convenience init 이란?

convenience init이란 클래스, 구조체의 인스턴스를 초기화할 때 사용되는 초기화 메서드 중 하나로 일반적으로 초기화 작업이나 초기화 간소화를 위해 사용되며 다른 초기화 메서드를 호출하는 형태로 작성됩니다.
convenience init은 부수적인 초기화 메서드입니다. 이를 통해 동일한 클래스 내에서 다른 초기화 메서드를 호출해, 초기화 로직을 집중화하거나 중복을 제거할 수 있습니다. convenience init은 반드시 지정 초기화 메서드를 호출해야 합니다.

class Person {
    var name: String
    var age: Int
    
    // 지정 초기화 메서드
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    // 부수적인 초기화 메서드
    convenience init(name: String) {
        self.init(name: name, age: 0)
    }
    
    convenience init() {
        self.init(name: "Unknown")
    }
}

let person1 = Person(name: "Alice", age: 30) // 지정 초기화 메서드 사용
let person2 = Person(name: "Bob")           // 부수적인 초기화 메서드 사용
let person3 = Person()                      // 또 다른 부수적인 초기화 메서드 사용

다음 예시 코드처럼 원래는 외부에서 값을 넣어주어야 하는 경우지만 객체의 특정 역할만을 수행하기에 외부에서 넣는 값이 중요하지 않은 경우가 있을 수 있습니다. 이 때는 convenience init을 통해 초기화 로직을 간소화 할 수 있습니다. 때문에 다양한 초기화 시나리오에 대응할 수 있는 유연성을 제공하게 됩니다.

convenience init을 사용하지 않았을 경우

만약 convenience init을 사용하지 않고 모든 초기화 메서드를 지정 초기화 메서드로 구현한다면,
1) 동일한 코드가 여러 메서드에 분산되어 작성될 수 있고 이로 인해 유지보수가 어려워질 수 있습니다.
2) 초기화 로직의 복잡성이 증가하면서 초기화 메서드 간의 관계를 파악하고 어렵고 어느 시점에 어느 초기화 메서드를 호출하는지 쉽게 알기 어려울 것입니다.

class Vehicle {
    var brand: String
    var model: String
    var year: Int
    var isNew: Bool?
    
    init(brand: String, model: String, year: Int) {
        self.brand = brand
        self.model = model
        self.year = year
    }
    
    init(brand: String, model: String, year: Int, isNew: Bool?) {
        self.brand = brand
        self.model = model
        self.year = year
        self.isNew = isNew
    }
}

convenience init을 다양한 초기화 시나리오에 대응할 수 있는 유연성을 제공하면서 초기화 과정에서 복잡성을 줄일 수 있을 것 같습니다.

Leave a Comment