← Назад к вопросам

Когда используешь MVVM, объявляешь модели классами или структурами?

2.0 Middle🔥 231 комментариев
#Архитектура и паттерны

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Ключевой выбор: class или struct для моделей в MVVM

В архитектуре MVVM (Model-View-ViewModel) выбор между классом (class) и структурой (struct) для объявления моделей зависит от нескольких факторов: семантики данных, требований к производительности и особенностей Swift. Рекомендуется использовать структуры (struct) по умолчанию, и вот почему:

Преимущества использования структур (struct)

  1. Безопасность и неизменяемость по умолчанию
    Структуры являются value types (типами-значениями). При передаче между компонентами (например, из ViewModel во View) создается копия, что предотвращает случайные изменения данных в нескольких местах. Это критически важно для моделей данных, которые часто должны оставаться неизменяемыми.

  2. Отсутствие проблем с ссылочной семантикой
    Классы — это reference types (ссылочные типы), что может привести к сложным багам, когда несколько ViewModel или объектов ссылаются на один экземпляр модели. Например, изменение модели в одном месте непреднамеренно повлияет на другие.

    // Проблема с class
    class UserClass {
        var name: String
        init(name: String) { self.name = name }
    }
    let user1 = UserClass(name: "Иван")
    let user2 = user1 // user2 ссылается на тот же объект
    user2.name = "Петр"
    print(user1.name) // "Петр" – неожиданное изменение!
    
    // Решение с struct
    struct UserStruct {
        let name: String
    }
    var user3 = UserStruct(name: "Иван")
    var user4 = user3 // Создается копия
    user4.name = "Петр" // Ошибка компиляции, если `name` – let
    
  3. Производительность и оптимизация
    Swift оптимизирует структуры через механизмы copy-on-write (копирование при записи), особенно для больших типов. Это обеспечивает эффективность работы с памятью без накладных расходов на подсчет ссылок, как у классов (reference counting).

  4. Согласованность с фреймворками SwiftUI и Combine
    В современных iOS-приложениях с SwiftUI и Combine структуры являются стандартом. Например, в SwiftUI @State и @Published лучше работают с value types, что способствует реактивным обновлениям интерфейса.

Когда использовать классы (class)

Классы подходят для моделей, если:

  • Требуется наследование (например, общая базовая модель с расширениями для разных сценариев).
  • Модель должна быть объектом со сложным жизненным циклом, например, интегрирована с Objective-C runtime или требует деинициализатора (deinit) для очистки ресурсов.
  • Работаете с фреймворками, ожидающими reference types (например, некоторые части UIKit).

Пример реализации модели в MVVM со структурой

// Model как struct
struct User: Codable, Identifiable {
    let id: UUID
    let name: String
    let email: String
    var lastLoginDate: Date?
    
    // Вычисляемое свойство для бизнес-логики
    var isActive: Bool {
        guard let lastLogin = lastLoginDate else { return false }
        return Calendar.current.dateComponents([.day], 
               from: lastLogin, to: Date()).day ?? 0 < 30
    }
}

// ViewModel с использованием модели
final class UserViewModel: ObservableObject {
    @Published private(set) var user: User
    private let service: NetworkService
    
    init(user: User, service: NetworkService) {
        self.user = user
        self.service = service
    }
    
    func updateName(_ newName: String) {
        // Создаем новую структуру с обновленным значением
        user = User(id: user.id, name: newName, 
                    email: user.email, lastLoginDate: user.lastLoginDate)
    }
}

Рекомендации по проектированию

  • Используйте struct со let-свойствами для неизменяемых данных. Если требуется изменение, создавайте новую структуру — это соответствует принципам функционального программирования.
  • Реализуйте протоколы Equatable и Hashable для удобного сравнения и использования в коллекциях.
  • Для сложных преобразований данных добавьте расширения (extensions) к структуре, сохраняя чистоту модели.

Итог

В MVVM на Swift модели чаще объявляют структурами (struct), что обеспечивает предсказуемость, безопасность данных и высокую производительность. Классы — это исключение для специфических случаев. Такой подход соответствует философии Swift и современным фреймворкам, что делает код надежнее и проще для поддержки.

Когда используешь MVVM, объявляешь модели классами или структурами? | PrepBro