Какие основные компоненты архитектурного паттерна Model-View-Controller (MVC)?

«Какие основные компоненты архитектурного паттерна Model-View-Controller (MVC)?» — вопрос из категории Архитектура, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

MVC разделяет ответственность приложения на три основных компонента с четкими ролями:

1. Model (Модель)

  • Ответственность: Представляет данные и бизнес-логику приложения.
  • Характеристики: Не зависит от пользовательского интерфейса (UI). Уведомляет об изменениях данных (часто через KVO, делегаты или замыкания).
  • Пример:
    struct User {
        let id: UUID
        var name: String
        var email: String
        // Методы валидации, бизнес-правила
        func isEmailValid() -> Bool { ... }
    }

2. View (Представление)

  • Ответственность: Визуальное отображение данных модели и обработка пользовательских событий (касания, свайпы).
  • Характеристики: Пассивно, не содержит бизнес-логику. Обычно является переиспользуемым, конфигурируемым компонентом (например, UILabel, UIButton, кастомная UIView).
  • Пример:
    class ProfileView: UIView {
        let nameLabel = UILabel()
        let emailLabel = UILabel()
        // Метод только для обновления UI
        func configure(with user: User) {
            nameLabel.text = user.name
            emailLabel.text = user.email
        }
    }

3. Controller (Контроллер)

  • Ответственность: Посредник между Model и View. Обрабатывает действия пользователя, обновляет Model и обновляет View в соответствии с изменениями Model.
  • Характеристики: Управляет жизненным циклом View. Часто становится «массивным» (Massive View Controller), так как в него переносят логику, не относящуюся напрямую к посредничеству.
  • Пример:

    class ProfileViewController: UIViewController {
        var user: User!
        let profileView = ProfileView()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            profileView.configure(with: user)
        }
    
        @objc func saveButtonTapped() {
            // 1. Получить данные из View (текст поля)
            // 2. Обновить Model
            // 3. Обновить View (показать индикатор/сообщение)
        }
    }

Проблема MVC в iOS (UIKit): Границы между View и Controller размыты – UIViewController по умолчанию владеет и управляет UIView, что часто приводит к созданию Massive View Controller. Для решения этой проблемы были разработаны другие паттерны: MVP, MVVM, VIPER.