디자인 패턴은 소프트웨어 개발에서 반복적으로 나타나는 문제들을 해결하기 위한 효율적인 방법들입니다. Swift 언어를 사용하여 개발하는 경우에도 다양한 디자인 패턴을 활용할 수 있습니다. 이 글에서는 몇 가지 대표적인 Swift 디자인 패턴에 대해 소개하겠습니다.
1. MVC (Model-View-Controller)
MVC는 애플리케이션의 구조를 세 가지 주요 컴포넌트로 분리하는 패턴입니다.
- Model: 애플리케이션의 데이터와 비즈니스 로직을 담당합니다.
- View: 사용자 인터페이스를 담당하며, 데이터의 시각적 표현을 담당합니다.
- Controller: Model과 View 사이의 흐름을 제어하고 사용자의 입력에 대한 응답을 처리합니다.
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
메서드를 호출하여 최종 객체를 생성합니다.
참고 자료
- Swift Design Patterns by Tutorials Team at raywenderlich.com
- Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides