Что такое MVVM и в чем отличие от MVC
Что проверяют
Понимаете ли вы, кто о ком знает в каждой схеме, и почему в MVC на iOS контроллер разрастается.
Как отвечать
MVC в варианте Apple: модель хранит данные, представление отображает, контроллер посередине. Проблема в том, что контроллер оказывается связан и с тем и с другим: он владеет представлением, знает модель, обрабатывает события, ходит в сеть и форматирует данные. Отсюда и прозвище Massive View Controller, и трудность тестирования, потому что логика перемешана с жизненным циклом экрана.
MVVM разрывает эту связь. ViewModel держит состояние экрана и логику его подготовки, но ничего не знает о представлении: ни импорта UIKit, ни ссылок на контроллер. Представление подписывается на состояние и отправляет события в ViewModel.
final class JobsViewModel: ObservableObject {
@Published private(set) var items: [JobItem] = []
func load() async { items = await service.load().map(JobItem.init) }
}Связывание в SwiftUI встроено через @Published и ObservableObject, в UIKit его делают через Combine или замыкания.
Что это даёт: ViewModel тестируется без интерфейса обычными тестами, состояние экрана лежит в одном месте, контроллер худеет до отображения.
Цена честная: файлов больше, на простом экране схема избыточна, а сама по себе она не решает вопрос навигации, отсюда координаторы.
Где спотыкаются
Кладут в ViewModel ссылку на контроллер или импортируют UIKit, чем возвращают ту же связанность.
Считают MVVM заменой архитектуры целиком: это схема представления, а не слоёв приложения.
Не могут объяснить, чем ViewModel отличается от презентера в MVP (связыванием против явных вызовов).
Пишут всю логику в ViewModel, включая сеть, и получают ту же перегруженную сущность, только под другим именем.