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

Какие знаешь функциональные компоненты в MVVM?

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

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

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

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

Функциональные компоненты в архитектуре MVVM для iOS

В контексте MVVM (Model-View-ViewModel) на iOS под "функциональными компонентами" обычно понимают не отдельные UI-компоненты (как в React), а роли и механизмы, которые обеспечивают реактивную связь между слоями, особенно между ViewModel и View. Вот ключевые функциональные компоненты в iOS-реализации MVVM:

1. Связывание данных (Data Binding)

Это фундаментальный механизм, который автоматически синхронизирует состояние ViewModel с View. В iOS для этого используются:

  • Combine Framework (нативный, iOS 13+): Позволяет создавать реактивные потоки данных через Publisher и Subscriber.

    // ViewModel
    class UserViewModel {
        @Published var userName: String = ""
        @Published var isButtonEnabled: Bool = false
    }
    
    // View (ViewController)
    private var cancellables = Set<AnyCancellable>()
    
    func bindViewModel() {
        viewModel.$userName
            .receive(on: DispatchQueue.main)
            .assign(to: \.text, on: nameLabel)
            .store(in: &cancellables)
        
        viewModel.$isButtonEnabled
            .assign(to: \.isEnabled, on: submitButton)
            .store(in: &cancellables)
    }
    
  • RxSwift / ReactiveSwift: Сторонние реактивные библиотеки, которые предоставляют более мощный API для биндинга.

    // RxSwift пример
    viewModel.userName
        .bind(to: nameLabel.rx.text)
        .disposed(by: disposeBag)
    

2. Команды (Commands) и Действия (Actions)

Инкапсулируют пользовательские взаимодействия (например, нажатия кнопок) в ViewModel, что делает бизнес-логику тестируемой и отделённой от UI.

// ViewModel с командой
class LoginViewModel {
    var loginCommand: ((String, String) -> Void)?
    
    func performLogin(username: String, password: String) {
        // Валидация и сетевая логика
        loginCommand?(username, password)
    }
}

// View
viewModel.loginCommand = { [weak self] username, password in
    self?.showHomeScreen()
}

3. Наблюдаемые свойства (Observable Properties)

Свойства ViewModel, которые уведомляют View об изменениях. Реализуются через:

  • Property Observers (didSet): Простой, но нереактивный подход.
  • ObservableObject и @Published в SwiftUI: Нативная интеграция для SwiftUI.
// ObservableObject для SwiftUI
class ProfileViewModel: ObservableObject {
    @Published var followersCount: Int = 0
    
    func fetchFollowers() {
        // Сетевая задача
        followersCount = 150
    }
}

4. Координаторы / Маршрутизаторы (Coordinators / Routers)

Отвечают за навигацию и переходы между экранами, что позволяет ViewModel не зависеть от UIKit/SwiftUI навигации.

protocol LoginCoordinatorProtocol {
    func showHomeScreen()
    func showForgotPassword()
}

class LoginViewModel {
    private let coordinator: LoginCoordinatorProtocol
    
    init(coordinator: LoginCoordinatorProtocol) {
        self.coordinator = coordinator
    }
    
    func onLoginSuccess() {
        coordinator.showHomeScreen()
    }
}

5. Сервисы и Зависимости (Services & Dependencies)

Функциональные компоненты для инкапсуляции бизнес-логики (сетевые запросы, работа с базой данных, аналитика), которые инжектятся в ViewModel.

protocol NetworkServiceProtocol {
    func fetchUserData(completion: @escaping (Result<User, Error>) -> Void)
}

class UserViewModel {
    private let networkService: NetworkServiceProtocol
    
    init(networkService: NetworkServiceProtocol) {
        self.networkService = networkService
    }
    
    func loadUser() {
        networkService.fetchUserData { result in
            // Обработка результата
        }
    }
}

6. Трансформаторы данных (Data Transformers)

Функции или классы, которые преобразуют сырые данные из Model в формат, пригодный для отображения в View.

// ViewModel с трансформацией
class ProductViewModel {
    private let product: Product
    
    var formattedPrice: String {
        NumberFormatter.currencyFormatter.string(from: product.price) ?? ""
    }
    
    var availabilityText: String {
        product.isAvailable ? "В наличии" : "Нет в наличии"
    }
}

7. Валидаторы (Validators)

Отдельные компоненты для проверки пользовательского ввода, которые могут быть переиспользованы между разными ViewModel.

struct EmailValidator {
    static func isValid(_ email: String) -> Bool {
        let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
        return NSPredicate(format: "SELF MATCHES %@", emailRegEx).evaluate(with: email)
    }
}

// Использование в ViewModel
class RegistrationViewModel {
    func validateEmail(_ email: String) -> Bool {
        return EmailValidator.isValid(email)
    }
}

Ключевые преимущества такого подхода:

  • Тестируемость: ViewModel может быть протестирована без UI.
  • Разделение ответственности: Чёткие границы между слоями.
  • Реактивность: Автоматическое обновление UI при изменении данных.
  • Поддержка SwiftUI и UIKit: Большинство компонентов работают в обеих парадигмах.

Эти функциональные компоненты превращают MVVM из простой схемы в полноценную архитектуру, пригодную для сложных iOS-приложений. Они обеспечивают масштабируемость, поддерживаемость и простоту тестирования кодовой базы.

Какие знаешь функциональные компоненты в MVVM? | PrepBro