Паттерны проектирования в Swift с примерами кода для iOS

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Паттерны проектирования в Swift: практическое руководство для iOS/macOS разработчиков

Паттерны проектирования (design patterns) — это проверенные решения типовых задач в разработке программного обеспечения. Для iOS/macOS разработчиков знание паттернов на Swift — обязательный навык, позволяющий создавать масштабируемые, тестируемые и поддерживаемые приложения. В этой статье мы разберем 4 ключевых паттерна с реальными примерами кода.

1. Singleton (Одиночка)

Один из самых популярных паттернов в iOS-разработке. Гарантирует, что у класса есть только один экземпляр, и предоставляет глобальную точку доступа к нему. Используется для управления общими ресурсами: UserDefaults, NetworkManager, Database.

Реализация Singleton в Swift

class NetworkManager {
    static let shared = NetworkManager()
    
    private init() { }
    
    func fetchData(from url: URL) {
        // логика запроса
        print("Данные получены из \(url)")
    }
}

// Использование
NetworkManager.shared.fetchData(from: URL(string: "https://api.example.com")!)

Важно: В Swift 5.5+ используйте actor для потокобезопасности:

actor SettingsManager {
    static let shared = SettingsManager()
    private var settings: [String: String] = [:]
    
    func setValue(_ value: String, forKey key: String) {
        settings[key] = value
    }
    
    func getValue(forKey key: String) -> String? {
        return settings[key]
    }
}

2. Factory Method (Фабричный метод)

Определяет интерфейс для создания объектов, но позволяет подклассам изменять тип создаваемых объектов. Идеально подходит для создания различных типов UI-компонентов или моделей данных.

Пример: создание кнопок для разных платформ

protocol Button {
    func render()
}

class iOSButton: Button {
    func render() {
        print("Отображаем iOS кнопку с закругленными углами")
    }
}

class macOSButton: Button {
    func render() {
        print("Отображаем macOS кнопку с градиентом")
    }
}

protocol ButtonFactory {
    func createButton() -> Button
}

class iOSButtonFactory: ButtonFactory {
    func createButton() -> Button {
        return iOSButton()
    }
}

class macOSButtonFactory: ButtonFactory {
    func createButton() -> Button {
        return macOSButton()
    }
}

// Использование
let factory: ButtonFactory = iOSButtonFactory()
let button = factory.createButton()
button.render() // "Отображаем iOS кнопку с закругленными углами"

3. Observer (Наблюдатель)

Позволяет объектам подписываться на события и получать уведомления об изменениях. В Swift реализуется через NotificationCenter, Combine или didSet.

Реализация через Combine (iOS 13+)

import Combine

class WeatherStation {
    @Published var temperature: Double = 0.0
    
    func updateTemperature(_ temp: Double) {
        temperature = temp
    }
}

class WeatherDisplay {
    var subscriptions = Set<AnyCancellable>()
    let station = WeatherStation()
    
    func startObserving() {
        station.$temperature
            .sink { [weak self] newTemp in
                print("Температура изменилась: \(newTemp)°C")
                self?.updateUI(with: newTemp)
            }
            .store(in: &subscriptions)
    }
    
    private func updateUI(with temp: Double) {
        // Обновление интерфейса
    }
}

Классическая реализация через протокол

protocol Observer: AnyObject {
    func update(value: Int)
}

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

class ConcreteObserver: Observer {
    let name: String
    
    init(name: String) {
        self.name = name
    }
    
    func update(value: Int) {
        print("\(name) получил новое значение: \(value)")
    }
}

// Использование
let subject = Subject()
let observer1 = ConcreteObserver(name: "Наблюдатель 1")
let observer2 = ConcreteObserver(name: "Наблюдатель 2")

subject.attach(observer1)
subject.attach(observer2)
subject.notify(value: 42)

4. Delegate (Делегат)

Фундаментальный паттерн для iOS/macOS. Позволяет одному объекту делегировать выполнение задач другому объекту. Широко используется в UIKit: UITableViewDelegate, UITextFieldDelegate.

Создание собственного делегата

protocol PaymentDelegate: AnyObject {
    func paymentDidComplete(amount: Double)
    func paymentDidFail(error: Error)
}

class PaymentManager {
    weak var delegate: PaymentDelegate?
    
    func processPayment(amount: Double) {
        // Логика обработки платежа
        let success = Bool.random()
        
        if success {
            delegate?.paymentDidComplete(amount: amount)
        } else {
            let error = NSError(domain: "PaymentError", code: -1)
            delegate?.paymentDidFail(error: error)
        }
    }
}

class ViewController: UIViewController, PaymentDelegate {
    let paymentManager = PaymentManager()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        paymentManager.delegate = self
    }
    
    @IBAction func payButtonTapped() {
        paymentManager.processPayment(amount: 99.99)
    }
    
    // MARK: - PaymentDelegate
    func paymentDidComplete(amount: Double) {
        showAlert(message: "Оплата \(amount) руб. прошла успешно!")
    }
    
    func paymentDidFail(error: Error) {
        showAlert(message: "Ошибка: \(error.localizedDescription)")
    }
    
    private func showAlert(message: String) {
        let alert = UIAlertController(title: "Результат", message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        present(alert, animated: true)
    }
}

Заключение

Освоение паттернов проектирования в Swift — ключевой шаг к профессиональной разработке под iOS/macOS. Мы рассмотрели:

  • Singleton — для управления единственным экземпляром (NetworkManager, UserDefaults)
  • Factory — для гибкого создания объектов без привязки к конкретным классам
  • Observer — для реактивного обновления интерфейса (Combine, NotificationCenter)
  • Delegate — для развязывания компонентов и обработки событий

На практике комбинируйте эти паттерны с архитектурными подходами (MVVM, VIPER) для создания надежных приложений. Помните: паттерны — это инструменты, а не догмы. Выбирайте их осознанно, исходя

Блоги

Рекомендаций по книгам