Swift 개발자라면 꼭 알고 있어야 할 디자인 패턴(Design Patterns) 에 대해 알아보겠습니다. 디자인 패턴은 효율적이고 유지보수하기 쉬운 코드를 작성하기 위한 검증된 설계 방법이에요. 이번 글에서는 Swift에서 자주 사용되는 디자인 패턴을 중심으로 개념, 특징, 그리고 실습 예제를 통해 쉽게 이해할 수 있도록 정리해드릴게요!
🎨 Swift 디자인 패턴 완전 정리
– 효율적인 코드 작성을 위한 필수 설계 전략!
✅ 디자인 패턴이란 무엇인가요?
디자인 패턴(Design Pattern)이란,
반복적으로 발생하는 문제를 해결하기 위한 최고의 설계 방식입니다. 복잡한 소프트웨어를 개발할 때, 문제를 매번 새롭게 해결하기보다는 검증된 설계 방법을 활용하면 더 안정적이고 효율적인 코드를 만들 수 있어요. Swift에서도 다양한 디자인 패턴이 활용됩니다.
🚀 Swift에서 자주 사용하는 디자인 패턴 TOP 7
패턴명 |
설명 |
---|---|
Singleton |
하나의 인스턴스만 생성 |
Delegate |
객체 간 의사소통 (이벤트 전달) |
MVC |
앱 구조를 Model-View-Controller로 분리 |
Observer |
변화 감지 및 알림 |
Factory |
객체 생성을 캡슐화 |
Strategy |
알고리즘을 동적으로 교체 |
Builder |
복잡한 객체 생성 절차 관리 |
1️⃣ 싱글톤 패턴 (Singleton)
앱 전체에서 하나의 인스턴스만 사용하는 패턴
예제: 설정 관리 클래스
class Settings {
static let shared = Settings()
private init() {}
var theme: String = "Light"
}
Settings.shared.theme = "Dark"
-
전역 상태 관리에 유용
-
남용하면 코드가 의존적이 될 수 있으니 주의!
2️⃣ 델리게이트 패턴 (Delegate)
객체 간 소통을 위한 대표적인 패턴
iOS 개발에서 가장 많이 사용되는 패턴!
예제: 다운로드 완료 알림
protocol DownloadDelegate: AnyObject {
func downloadDidFinish()
}
class Downloader {
weak var delegate: DownloadDelegate?
func startDownload() {
// 다운로드 완료 시
delegate?.downloadDidFinish()
}
}
-
이벤트 전달용으로 사용
-
반드시 weak 참조로 설정 (순환 참조 방지)
3️⃣ MVC 패턴 (Model-View-Controller)
앱 구조를 세 부분으로 분리해서 관리
구성요소 |
역할 |
---|---|
Model |
데이터와 비즈니스 로직 |
View |
화면(UI) |
Controller |
중간 조율자 |
Swift의 UIKit 기반 앱은 기본적으로 MVC 구조를 따릅니다.
4️⃣ 옵저버 패턴 (Observer)
상태 변화가 발생하면 자동으로 알림을 보내는 패턴
예제: NotificationCenter 활용
NotificationCenter.default.addObserver(self, selector: #selector(handleEvent), name: .init("EventOccurred"), object: nil)
NotificationCenter.default.post(name: .init("EventOccurred"), object: nil)
-
데이터 변경 사항을 여러 객체에 알릴 때 유용
-
SwiftUI에서는 @Published, @ObservedObject 등이 이 패턴을 적용한 사례!
5️⃣ 팩토리 패턴 (Factory)
객체 생성 로직을 분리해서 관리하는 패턴
예제:
class AnimalFactory {
static func createAnimal(type: String) -> Animal {
switch type {
case "Dog": return Dog()
case "Cat": return Cat()
default: return Animal()
}
}
}
-
객체 생성 방식이 바뀌어도 코드 수정 최소화 가능!
6️⃣ 전략 패턴 (Strategy)
알고리즘을 유연하게 교체할 수 있는 패턴
예제:
protocol PaymentStrategy {
func pay(amount: Int)
}
class CardPayment: PaymentStrategy {
func pay(amount: Int) {
print("카드로 \(amount)원 결제")
}
}
class CashPayment: PaymentStrategy {
func pay(amount: Int) {
print("현금으로 \(amount)원 결제")
}
}
class PaymentContext {
var strategy: PaymentStrategy
init(strategy: PaymentStrategy) {
self.strategy = strategy
}
func executePayment(amount: Int) {
strategy.pay(amount: amount)
}
}
-
런타임 중 전략 변경 가능!
7️⃣ 빌더 패턴 (Builder)
복잡한 객체 생성 과정을 단계별로 관리
Swift에서는 주로 메서드 체이닝 방식으로 구현합니다.
class BurgerBuilder {
private var ingredients: [String] = []
func addLettuce() -> BurgerBuilder {
ingredients.append("Lettuce")
return self
}
func addPatty() -> BurgerBuilder {
ingredients.append("Patty")
return self
}
func build() -> String {
return "Burger with " + ingredients.joined(separator: ", ")
}
}
let burger = BurgerBuilder().addLettuce().addPatty().build()
print(burger) // Burger with Lettuce, Patty
빌더 패턴 (Builder) |
✏️ 실습 아이디어
-
싱글톤 패턴으로 로그인 상태 관리 클래스 만들기
-
델리게이트 패턴을 활용한 사용자 입력 이벤트 처리
-
팩토리 패턴으로 다양한 UI 버튼 생성기 만들기
-
옵저버 패턴으로 설정 변경 감지 시스템 구현
-
전략 패턴으로 배송 방법 선택 시스템 설계
✅ 1. 싱글톤 패턴 – 로그인 상태 관리 클래스
class LoginManager {
static let shared = LoginManager()
private init() {}
private(set) var isLoggedIn = false
private(set) var username: String?
func login(user: String) {
isLoggedIn = true
username = user
print("🔐 \(user) 로그인 완료")
}
func logout() {
isLoggedIn = false
username = nil
print("🔓 로그아웃 완료")
}
}
// 사용 예시
LoginManager.shared.login(user: "peter")
print(LoginManager.shared.isLoggedIn) // true
LoginManager.shared.logout()
싱글톤 패턴 – 로그인 상태 관리 클래스 |
✅ 2. 델리게이트 패턴 – 사용자 입력 이벤트 처리
protocol InputDelegate: AnyObject {
func didSubmitInput(_ text: String)
}
class TextField {
weak var delegate: InputDelegate?
func simulateUserTyping(text: String) {
print("⌨️ 입력됨: \(text)")
delegate?.didSubmitInput(text)
}
}
class ViewController: InputDelegate {
func didSubmitInput(_ text: String) {
print("📥 사용자가 입력한 값 처리 중: \(text)")
}
}
// 사용 예시
let inputField = TextField()
let vc = ViewController()
inputField.delegate = vc
inputField.simulateUserTyping(text: "Hello Swift!")
델리게이트 패턴 – 사용자 입력 이벤트 처리 |
✅ 3. 팩토리 패턴 – 다양한 UI 버튼 생성기
import UIKit
protocol UIButtonStyle {
func makeButton() -> UIButton
}
class PrimaryButton: UIButtonStyle {
func makeButton() -> UIButton {
let button = UIButton()
button.setTitle("Primary", for: .normal)
button.backgroundColor = .systemBlue
return button
}
}
class DangerButton: UIButtonStyle {
func makeButton() -> UIButton {
let button = UIButton()
button.setTitle("Danger", for: .normal)
button.backgroundColor = .systemRed
return button
}
}
class ButtonFactory {
static func createButton(style: String) -> UIButton {
switch style {
case "primary": return PrimaryButton().makeButton()
case "danger": return DangerButton().makeButton()
default: return UIButton()
}
}
}
// 사용 예시 (UIViewController 내부라면)
let button = ButtonFactory.createButton(style: "danger")
// button을 화면에 추가
✅ 4. 옵저버 패턴 – 설정 변경 감지 시스템
class Settings {
static let shared = Settings()
var observers: [SettingsObserver] = []
var darkMode: Bool = false {
didSet {
observers.forEach { $0.didChangeDarkMode(to: darkMode) }
}
}
func addObserver(_ observer: SettingsObserver) {
observers.append(observer)
}
}
protocol SettingsObserver {
func didChangeDarkMode(to enabled: Bool)
}
class ViewController: SettingsObserver {
func didChangeDarkMode(to enabled: Bool) {
print("🌙 다크모드 변경됨 → \(enabled ? "ON" : "OFF")")
}
}
// 사용 예시
let vc = ViewController()
Settings.shared.addObserver(vc)
Settings.shared.darkMode = true
옵저버 패턴 – 설정 변경 감지 시스템 |
✅ 5. 전략 패턴 – 배송 방법 선택 시스템
protocol DeliveryStrategy {
func deliver(item: String)
}
class FastDelivery: DeliveryStrategy {
func deliver(item: String) {
print("🚚 빠른 배송으로 \(item) 보내기")
}
}
class StandardDelivery: DeliveryStrategy {
func deliver(item: String) {
print("📦 일반 배송으로 \(item) 보내기")
}
}
class DeliveryContext {
var strategy: DeliveryStrategy
init(strategy: DeliveryStrategy) {
self.strategy = strategy
}
func send(item: String) {
strategy.deliver(item: item)
}
}
// 사용 예시
let context = DeliveryContext(strategy: FastDelivery())
context.send(item: "아이폰") // 🚚 빠른 배송으로 아이폰 보내기
context.strategy = StandardDelivery()
context.send(item: "맥북") // 📦 일반 배송으로 맥북 보내기
전략 패턴 – 배송 방법 선택 시스템 |
🎯 요약
실습 주제 |
핵심 설계 패턴 |
주요 포인트 |
---|---|---|
로그인 상태 관리 |
싱글톤(Singleton) |
앱 전역에서 상태 공유 |
사용자 입력 처리 |
델리게이트(Delegate) |
사용자와 UI 간 이벤트 전달 |
UI 버튼 생성 |
팩토리(Factory) |
스타일별 생성 분리 |
설정 변경 감지 |
옵저버(Observer) |
상태 변화 감지 및 반응 |
배송 전략 선택 |
전략(Strategy) |
런타임에 알고리즘 교체 |
🎯 마무리하며
디자인 패턴은 단순히 “형식적인 코드”가 아닙니다. 효율적이고 유지보수하기 쉬운 구조를 만들기 위한 개발자의 지혜입니다!
Swift 개발에서 자주 쓰이는 패턴을 잘 익히면:
-
코드 재사용성 향상
-
확장성 있는 앱 설계
-
팀 프로젝트에서 일관된 코드 유지
-
문제 해결 속도 향상
댓글 쓰기