Ответ
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.