[swift] Swift 디자인 패턴 종류 소개

디자인 패턴은 소프트웨어 개발에서 반복적으로 나타나는 문제들을 해결하기 위한 효율적인 방법들입니다. Swift 언어를 사용하여 개발하는 경우에도 다양한 디자인 패턴을 활용할 수 있습니다. 이 글에서는 몇 가지 대표적인 Swift 디자인 패턴에 대해 소개하겠습니다.

1. MVC (Model-View-Controller)

MVC는 애플리케이션의 구조를 세 가지 주요 컴포넌트로 분리하는 패턴입니다.

MVC 패턴은 애플리케이션의 유지 보수성과 확장성을 높일 수 있는 장점이 있습니다.

2. Singleton

싱글톤은 애플리케이션에서 하나의 인스턴스만 존재하도록 보장하는 패턴입니다. 이는 전역 변수를 사용하지 않고 인스턴스를 공유할 때 유용합니다.

class MySingleton {
    static let shared = MySingleton()
    
    private init() {}
    
    func doSomething() {
        // 싱글톤 동작 내용
    }
}

위의 예제에서 shared라는 정적 프로퍼티를 사용하여 하나의 인스턴스를 생성하고 공유하고 있습니다.

3. Observer

옵저버 패턴은 객체 간의 일대다(dependency) 관계를 정의하는 패턴입니다. 한 객체의 상태 변화가 다른 객체에게 자동으로 통지되어 수행할 작업을 정의할 수 있습니다.

protocol Subject {
    func attach(observer: Observer)
    func detach(observer: Observer)
    func notify()
}

protocol Observer {
    func update()
}

class ConcreteSubject: Subject {
    private var observers: [Observer] = []
    
    func attach(observer: Observer) {
        observers.append(observer)
    }
    
    func detach(observer: Observer) {
        observers.removeAll(where: { $0 === observer })
    }
    
    func notify() {
        observers.forEach { $0.update() }
    }
}

class ConcreteObserver: Observer {
    func update() {
        // 옵저버 동작 내용
    }
}

위의 예제는 옵저버 패턴을 구현한 코드입니다. Subject 프로토콜은 옵저버를 추가, 제거 및 통지하는 메서드를 정의하고, Observer 프로토콜은 업데이트를 수행하는 메서드를 정의합니다. ConcreteSubject는 옵저버들의 리스트를 관리하며, 변화가 발생할 경우 옵저버들에게 알립니다. ConcreteObserver는 실질적인 옵저버 역할을 수행합니다.

4. Builder

빌더 패턴은 복잡한 객체 생성 과정을 단순화하기 위한 패턴입니다. 객체를 생성하는데 필요한 많은 매개변수를 가진 경우, 빌더 패턴을 사용하면 객체를 보다 간편하게 생성할 수 있습니다.

class Product {
    var property1: String
    var property2: Int
    // ...
    
    init(property1: String, property2: Int /* ... */) {
        self.property1 = property1
        self.property2 = property2
        // ...
    }
}

class ProductBuilder {
    private var property1: String = ""
    private var property2: Int = 0
    // ...
    
    func setProperty1(_ property1: String) -> Self {
        self.property1 = property1
        return self
    }
    
    func setProperty2(_ property2: Int) -> Self {
        self.property2 = property2
        return self
    }
    
    // ...
    
    func build() -> Product {
        return Product(property1: property1, property2: property2 /* ... */)
    }
}

let product = ProductBuilder()
    .setProperty1("value1")
    .setProperty2(42)
    // ...
    .build()

위의 예제는 빌더 패턴을 활용하여 Product 객체를 생성하는 코드입니다. Product 클래스의 초기화에 필요한 매개변수를 ProductBuilder를 통해 설정한 후 build 메서드를 호출하여 최종 객체를 생성합니다.

참고 자료