01.10.2024 старт набору нової групи на курс Enterprise Patterns! Реєструйтеся зараз зі знижкою 30%!
Дізнатися більше
06.08.2022
5 хвилин перегляду

Принципи ООП. 3. Поліморфізм

Сергій Немчинський
Принципи ООП. 3. Поліморфізм

Це третя лекція з міні-курсу про принципи ООП, і тема її – поліморфізм.

Поліморфізм, напевно, найважливіший принцип ООП: на його основі будується величезна кількість патернів і рішень. Саме через поліморфізму ООП така потужна і класна штука, яка дозволяє не писати один і той же код по 50 разів, а дублювати його і використовувати для роботи з іншими даними.

Визначення поліморфізму – «здатність функції використовувати дані різних типів». Просто, щоб не просто. Якщо задуматися, то функція може використовувати дані різних типів по-різному. Є два типи поліморфізму: поліморфізм ad-hoc, тобто за запитом, і параметричний, або істинний поліморфізм.

Перший тип поліморфізму (ad-hoc) – це поліморфізм за запитом. Це банальні речі: приведення даних – коли метод отримує дані, наведені до того типу, з яким він зазвичай працює – і перевантаження методів, коли метод існує в декількох варіантах, з однаковою назвою, але різними параметрами. Це несправжній поліморфізм. Якщо це перевантаження, то це різні методи: вони мають різний тіло, який же це поліморфізм? Якщо ми говоримо про приведення даних, то тіло методу одне, але воно працює з одним типом даних, тому що до входу в метод параметр був перетворений в потрібний тип даних. Такий недороблений поліморфізм.

Параметричний, або справжній поліморфізм, це коли функція, одна і та ж, з одним і тим же тілом, може приймати в якості параметра дані різних класів. Як це можливо? Ну, наприклад, коли параметром функції є базовий клас для деякої ієрархії об’єктів. Тому функція може приймати будь-який з підкласів цього класу. Як ми говорили в минулій лекції, спадкоємець пов’язаний з базовим класом. Якщо параметр функції – базовий клас, будь спадкоємець може прийти туди і бути оброблений. Опрацьовано він може бути по-різному, може бути однаково, все залежить від внутрішньої структури цих об’єктів і того, як написаний метод.

Про корисність поліморфізму. Якось в книзі когось із великих програмістів я зустрів думка, яка спочатку мене здивувала. «Все IF в програмі можна замінити поліморфізмом». Думка про те, що всі умовні розгалуження в програмі можна замінити поліморфізмом, спочатку підірвала мені мозок. Але потім я зрозумів, що дійсно, будь-if в програмі можна замінити на поліморфізм, тобто Одна гілка йде в одного спадкоємця базового класу, інша гілка (else) – в іншого. Якщо немає ніякої гілки, то залишається порожнє місце – метод нічого не робить.

Якщо ви задумаєтеся, то зрозумієте, що поліморфізм допомагає зменшувати розмір програми на порядки. Саме за допомогою поліморфізму ви зможете забезпечити гнучкість і уникнути перевантаженості коду. Найстрашніший код, який попадався мені в житті – це п’ять тисяч рядків if-ів. І вся ця простирадло в п’ять тисяч рядків коду могла бути схлопнуться в невелике дерево успадкування. Це один з найпоширеніших способів рефакторінга. Поліморфізм якраз є способом уникнути заплутаного, складного і важко підтримуваного коду.

Сучасна програмна інженерія прийшла в стан, коли ми практично відмовилися від спадкування. Немає спадкування – немає справжнього поліморфізму. Але якщо поглянути на всі існуючі патерни, починаючи з декораторів, майже всі вони побудовані на поліморфізмі. Якщо у вашому коді немає успадкування, немає поліморфізму, то ваш код не є ООП-кодом. Це дуже погано.

Але, на жаль, всі відомі мені сучасні мені фреймворки у всіх мовах заохочують використання об’єкти доменної моделі без поведінки і сервіси без стану. А при цьому поліморфізм неможливий, і ви отримуєте процедурний код в середині своєї програми. Це дуже сумно, але я сподіваюся, що історія зробить ще одне коло і ми повернемося до багатих об’єктів.

Додати коментар

Ваш імейл не буде опубліковано. Обов'язкові поля відзначені *

Зберегти моє ім'я, імейл та адресу сайту у цьому браузері для майбутніх коментарів