Swift에서 싱글턴, 옵저버, 팩토리 같은 디자인 패턴 구현하기: 디자인 패턴을 통한 코드의 유지보수성 향상.

작성일 :

Swift에서 디자인 패턴 구현하기

싱글턴 패턴

싱글턴 패턴은 클래스의 인스턴스가 하나만 생성되도록 보장하는 디자인 패턴입니다. 이 패턴은 보통 애플리케이션 전역에서 공유되어야 하는 로직에 유용합니다. Swift에서는 static 키워드를 사용하여 싱글턴 패턴을 쉽게 구현할 수 있습니다.

Swift에서의 싱글턴 구현 예제

swift
class Singleton {
    static let shared = Singleton()
    private init() {}

    func doSomething() {
        print("싱글턴 패턴을 사용한 메서드 호출")
    }
}

// 사용 예시
Singleton.shared.doSomething()

이 예제에서는 Singleton 클래스의 인스턴스가 오직 하나만 생성됩니다. static let shared는 싱글턴 인스턴스를 생성하는 데 사용되며, 한 번 생성된 후에는 어플리케이션의 전역에서 동일한 인스턴스를 사용할 수 있습니다. private init()은 외부에서 추가 인스턴스 생성을 막아줍니다.

옵저버 패턴

옵저버 패턴은 객체의 상태 변화가 다른 객체에 의해 자동으로 통지되도록 하는 패턴입니다. 이 패턴은 예를 들어 UI 업데이트나 데이터 동기화와 같은 상황에서 유용하게 쓰일 수 있습니다.

Swift에서의 옵저버 패턴 구현 예제

swift
protocol Observer: AnyObject {
    func update(subject: Subject)
}

class Subject {
    private lazy var observers = [Observer]()

    func addObserver(_ observer: Observer) {
        observers.append(observer)
    }

    func removeObserver(_ observer: Observer) {
        observers = observers.filter { $0 !== observer }
    }

    func notifyObservers() {
        for observer in observers {
            observer.update(subject: self)
        }
    }

    var state: Int = { didSet { notifyObservers() } }
}

class ConcreteObserver: Observer {
    func update(subject: Subject) {
        print("옵저버가 업데이트 되었음: \(subject.state)")
    }
}

// 사용 예시
let subject = Subject()
let observer = ConcreteObserver()
subject.addObserver(observer)
subject.state = 1  // 옵저버에게 알림이 전달됩니다

이 예제에서는 Subject 클래스가 상태를 가지고 있으며, 이 상태가 변경될 때마다 모든 옵저버들에게 알림을 전달합니다. 옵저버들은 update(subject:) 메서드를 통해 상태 변화를 반영할 수 있습니다.

팩토리 패턴

팩토리 패턴은 객체 생성 로직을 별도의 팩토리 클래스로 분리하는 패턴입니다. 이 패턴은 객체 생성 로직을 통제하고, 코드의 가독성을 높이며, 나중에 생성 로직을 변경하기 쉽게 해줍니다.

Swift에서의 팩토리 패턴 구현 예제

swift
protocol Product {
    func doSomething()
}

class ConcreteProductA: Product {
    func doSomething() {
        print("ConcreteProductA 작업 수행")
    }
}

class ConcreteProductB: Product {
    func doSomething() {
        print("ConcreteProductB 작업 수행")
    }
}

class Factory {
    enum ProductType {
        case typeA
        case typeB
    }

    static func createProduct(type: ProductType) -> Product {
        switch type {
        case .typeA:
            return ConcreteProductA()
        case .typeB:
            return ConcreteProductB()
        }
    }
}

// 사용 예시
let productA = Factory.createProduct(type: .typeA)
productA.doSomething()
let productB = Factory.createProduct(type: .typeB)
productB.doSomething()

여기서는 Factory 클래스가 제품 객체의 생성 책임을 맡습니다. createProduct(type:) 메서드를 사용하여, 구체적으로 어떤 제품을 생성할지 결정할 수 있으며, 새롭게 생성 로직이 필요할 때는 팩토리 클래스만 수정하면 됩니다.

결론

싱글턴, 옵저버, 팩토리와 같은 디자인 패턴은 코드의 유지보수성과 재사용성을 크게 향상시킵니다. Swift에서도 이러한 패턴을 효과적으로 구현할 수 있으며, 이를 통해 코드의 품질을 높이고 유지보수를 더욱 쉽게 만들 수 있습니다.