Protocol-Oriented Programming
Protocol-Oriented Programming (POP, «протокол-ориентированное программирование») — парадигма разработки программного обеспечения, в которой поведение типов описывается через протоколы (интерфейсы), а не через иерархии наследования классов[1].
Общие сведения
| Protocol-Oriented Programming | |
|---|---|
| англ. Protocol-Oriented Programming | |
| Область использования | Программирование, Разработка программного обеспечения |
| Дата появления | 2015 |
| Место появления | конференция WWDC |
| Автор понятия | Дэйв Абрахамс |
Определение
Protocol-Oriented Programming концентрируется на следующих принципах:
- протоколы выступают «чертежами» поведения и определяют методы, свойства и прочие требования, не задавая их реализацию[2];
- композиция поведения осуществляется путём одновременного принятия множественных протоколов, что снижает необходимость глубокой иерархии наследования[3];
- расширения протоколов позволяют давать реализации по умолчанию, сокращая дублирование кода;
- парадигма отлично работает с типами-значениями (структурами и перечислениями), сохраняя преимущества неизменяемости и безопасности[4];
- широкое использование дженериков повышает гибкость и повторное использование алгоритмов.
Структурные элементы Protocol-Oriented Programming
- Протоколы — контракты, задающие требования к типам.
- Расширения протоколов — механизм добавления реализаций по умолчанию.
- Композиция протоколов — возможность комбинировать несколько протоколов для одного типа.
- Типы-значения (Struct, Enum) — получают требуемое поведение без наследования классов.
- Дженерики — обеспечивают обобщённость алгоритмов при работе с протоколами.
- Слабая связанность — модули взаимодействуют через абстрактные контракты, упрощая тестирование и поддержку[5].
Протоколы
Протокол в Swift объявляется ключевым словом protocol и может содержать:
- требования к методам (экземплярным и типовым), включая изменяемые (метка
mutating); - требования к свойствам (только чтение —
{ get }, или чтение/запись —{ get set }); - сабскрипты;
- ассоциированные типы (
associatedtype) для обобщённости; - множественное наследование других протоколов[6].
Расширения прототолов
Расширения (extension) позволяют:
- предоставлять реализацию по умолчанию для любых требований протокола;
- добавлять вычисляемые свойства и вспомогательные методы;
- использовать условные расширения с
where-клаузой для ограничений на типы[7]; - реализовать «ретроактивное» моделирование, расширяя протоколами уже существующие типы.
Полиморфизм и динамическая диспетчеризация
Полиморфизм достигается путём обращения к объектам через переменные протокольного типа: конкретная реализация метода выбирается во время выполнения посредством динамической диспетчеризации[8]. Swift использует:
- статическую диспетчеризацию для методов, определённых в расширениях протокола без явного требования в самом протоколе (быстрее);
- witness table — таблицы соответствий протоколу, чтобы во время выполнения найти нужную реализацию;
- виртуальные таблицы (v-table) для классов;
- message dispatch (самая динамичная, унаследована от Objective-C)[9].
Этапы применения
Применение протокол-ориентированного программирования обычно включает несколько последовательных этапов.
1. Проектирование
На этом этапе формулируются доменные поведения в виде небольших протоколов:
- выделяется контракт для каждой отдельной ответственности (SRP);
- предпочтение отдаётся композиции протоколов вместо наследования классов;
- используются расширения для общих реализаций;
- проектируется API так, чтобы зависимости вводились через абстракции, повышая тестируемость.
2. Реализация
На этапе реализации:
- создаются типы (структуры, перечисления, классы), принимающие протоколы;
- добавляются реализации по умолчанию через расширения протоколов;
- активно применяются структуры и перечисления как типы-значения;
- осуществляется композиция протоколов (например,
typealias ReadableWritable = Readable & Writable); - используются ассоциированные типы и дженерики для повышения гибкости[10].
3. Тестирование
POP упрощает юнит-тестирование благодаря:
- лёгкому созданию моков и стабов, соответствующих тем же протоколам;
- низкой связанности кода и возможности изолировать тестируемый компонент;
- применению паттерна «Dependency Injection» через протокольные абстракции[11].
4. Оптимизация
На этапе оптимизации анализируются накладные расходы, связанные с динамической диспетчеризацией и упаковкой экзистенциальных контейнеров. Для их снижения:
- методы и классы помечаются как
finalилиprivateдля включения статической диспетчеризации; - используются непрозрачные типы (
some Protocol) вместоany; - проводится профилирование и включается оптимизация компилятора (-O) для релизных сборок[12].
5. Поддержка
Поддерживаемость POP-кода обеспечивается:
- модульной структурой и чёткими контрактами;
- возможностью добавлять новое поведение через расширения, не трогая существующий код;
- простотой рефакторинга благодаря отсутствию глубокой иерархии наследования[13].
Преимущества и недостатки
Преимущества
- Повторное использование кода за счёт реализаций по умолчанию.
- Слабая связанность и высокая модульность архитектуры.
- Улучшенная тестируемость через легко заменяемые зависимости.
- Поддержка типов-значений и неизменяемости, повышающая надёжность.
- Отсутствие ограничений единичного наследования — тип может соответствовать множеству протоколов.
Недостатки
- Более высокая кривая обучения для новичков.
- Риск чрезмерного дробления кода на мелкие протоколы.
- Отсутствие хранимых свойств в протоколах заставляет искать обходные пути.
- Возможные накладные расходы динамической диспетчеризации при неосторожном использовании[14].
Сферы применения
- разработка приложений для iOS, iPadOS, watchOS и macOS;
- создание обобщённых алгоритмов и коллекций в стандартной библиотеке Swift;
- построение сетевых слоёв, где каждый эндпоинт моделируется как тип, соответствующий протоколу;
- декларативные UI-фреймворки (например, SwiftUI);
- расширение функциональности сторонних типов без изменения их исходного кода[15].
Инструменты для использования в Protocol-Oriented Programming
Языки программирования с поддержкой Protocol-Oriented Programming
Фреймворки Protocol-Oriented Programming
- SwiftUI — каждый визуальный компонент соответствует протоколу
View, а модификации описываются черезViewModifier. - Стандартная библиотека Swift — типы
Array,Dictionary,Stringреализуют протоколыCollection,Sequenceи другие, демонстрируя POP-подход.
Библиотеки Protocol-Oriented Programming
- Moya — сетевой слой, где каждый эндпоинт описывается протоколом
TargetTypeи расширениями[20]. - RxSwift — реактивный фреймворк, активно использующий протоколы
ObservableTypeиObserverTypeдля описания потоков событий.
Интеграция с другими парадигмами
POP органично сочетается с:
- объектно-ориентированным программированием — классы могут соответствовать протоколам и получать поведение через композицию;
- функциональным программированием — расширения протоколов предоставляют методы высшего порядка (
map,filter), а неизменяемые структуры поддерживают чистые функции[21].
Примечания
- ↑ Protocol-Oriented Programming: Everything You Need to Know When Assessing Protocol-Oriented Programming Skills. alooba.com. Дата обращения: 20 июня 2025.
Protocols I: "Start With a Protocol," He Said - Cocoaphony. robnapier.net. Дата обращения: 20 июня 2025. - ↑ Documentation. swift.org. Дата обращения: 20 июня 2025.
- ↑ What is protocol-oriented programming in Swift? clouddevs.com. Дата обращения: 20 июня 2025.
- ↑ Протокольно-ориентированное программирование в Swift. apptractor.ru. Дата обращения: 20 июня 2025.
- ↑ Protocol-Oriented Programming: Everything You Need to Know When Assessing Protocol-Oriented Programming Skills. alooba.com. Дата обращения: 20 июня 2025.
- ↑ Протоколы – Портал дистанционного обучения Swiftbook. swiftbook.org. Дата обращения: 20 июня 2025.
- ↑ Documentation. swift.org. Дата обращения: 20 июня 2025.
- ↑ Полиморфизм в Swift: Основы, Примеры и Применение. bestprogrammer.ru. Дата обращения: 20 июня 2025.
Протокольно ориентированное программирование, часть 2 / Хабр. habr.com. Дата обращения: 20 июня 2025. - ↑ Как работает диспетчеризация методов в Swift / Tproger. tproger.ru. Дата обращения: 20 июня 2025.
- ↑ Protocol-Oriented Programming / Хабр. habr.com. Дата обращения: 20 июня 2025.
- ↑ Effective Swift Unit Testing: A Comprehensive Guide to XCTest Framework — Bugfender. bugfender.com. Дата обращения: 20 июня 2025.
Better unit testing with Swift — Masilotti.com. masilotti.com. Дата обращения: 20 июня 2025. - ↑ sridharan.net. sridharan.net. Дата обращения: 20 июня 2025.
- ↑ Протокольно-ориентированное программирование Swift. codeswift.ru. Дата обращения: 20 июня 2025.
- ↑ Protocol Oriented Programming is Not a Silver Bullet — Chris Eidhof. eidhof.nl. Дата обращения: 20 июня 2025.
- ↑ Protocol-Oriented Programming: The Best Tool of Expert iOS Developers. matteomanferdini.com. Дата обращения: 20 июня 2025.
- ↑ xcode - Is there any easiest way to implement all required methods of protocol in iOS? - Stack Overflow. stackoverflow.com. Дата обращения: 20 июня 2025.
- ↑ GitHub - realm/SwiftLint: A tool to enforce Swift style and conventions. github.com. Дата обращения: 20 июня 2025.
- ↑ Meta-programming in Swift. merowing.info. Дата обращения: 20 июня 2025.
- ↑ Trait-объекты и полиморфизм в Rust / Хабр. habr.com. Дата обращения: 20 июня 2025.
- ↑ PluginType Protocol Reference. moya.github.io. Дата обращения: 20 июня 2025.
- ↑ Composite Thrashing Code Adron's success in misadventures of thrashing coding and calamity! Swift: A Multi-Paradigm Powerhouse—OOP, POP, and FP. compositecode.blog. Дата обращения: 20 июня 2025.
| Правообладателем данного материала является АНО «Интернет-энциклопедия «РУВИКИ». Использование данного материала на других сайтах возможно только с согласия АНО «Интернет-энциклопедия «РУВИКИ». |