Что такое протокольно ориентированное программирование и его преимущества
Что проверяют
Понимаете ли вы, чем протокол с расширениями отличается от базового класса и почему Swift подталкивает к структурам. Следом почти всегда спрашивают про диспетчеризацию методов из расширения протокола или про разницу между some и any.
Как отвечать
Протокольно ориентированный подход в Swift это проектирование от протоколов и типов-значений вместо иерархий классов. Apple представила его на WWDC 2015 в докладе «Protocol-Oriented Programming in Swift». Каркас ответа:
- протокол как контракт: описывает требования (
func,var { get set },associatedtype), не навязывая хранение и базовый класс; - расширения протоколов: дают реализацию по умолчанию, общее поведение переиспользуется без наследования;
- типы-значения: протоколы принимают
structиenum, а класс в Swift наследуется только от одного родителя; - композиция: тип подписывается на несколько протоколов, а в параметре можно потребовать
Codable & Identifiable; - ретроактивное соответствие: протокол добавляется к чужому типу через
extension, хоть кString; - тестируемость: зависимость объявлена протоколом, в тесте подставляется заглушка без сабклассинга.
Отдельно про дженерики. some View в SwiftUI это непрозрачный тип: компилятор знает конкретный тип и специализирует код. any Protocol это экзистенциальный контейнер с динамической диспетчеризацией и накладными расходами, ключевое слово появилось в Swift 5.6. До Swift 5.7 протокол с associatedtype вообще нельзя было использовать как тип переменной.
Где спотыкаются
Не знают про статическую диспетчеризацию. Метод, объявленный только в расширении и не входящий в требования протокола, через переменную типа протокола вызовет реализацию по умолчанию, а не версию из конкретного типа.
Приводят UITableViewDelegate как главный пример POP. Это делегирование из Objective-C, опциональные методы там через @objc optional, а не через расширения.
Заявляют, что классы больше не нужны. Ссылочная семантика нужна для общего изменяемого состояния, идентичности объекта и работы с UIKit, POP её не отменяет.