Чим більше я дізнаюся про різні парадигми програмування, такі як функціональне програмування, тим більше я починаю ставити під сумнів розумність таких концепцій OOP, як спадкування та поліморфізм. Я вперше дізнався про спадщину та поліморфізм у школі, і в той час поліморфізм здавався чудовим способом написання загального коду, який дозволяв легко розширити.
Але в умовах типізації качок (як динамічних, так і статичних) та функціональних особливостей, таких як функції вищого порядку, я почав розглядати спадкування та поліморфізм як накладення зайвого обмеження, заснованого на крихкому наборі відносин між об'єктами. Загальна ідея поліморфізму полягає в тому, що ви пишете функцію один раз, а пізніше ви можете додавати нову функціональність у свою програму, не змінюючи початкову функцію - все, що вам потрібно зробити, це створити ще один похідний клас, який реалізує необхідні методи.
Але цього набагато простіше досягти за допомогою набору качок, будь то в динамічній мові, як Python, або в статичній мові на зразок C ++.
Як приклад, розглянемо наступну функцію Python з наступним її статичним еквівалентом C ++:
def foo(obj):
obj.doSomething()
template <class Obj>
void foo(Obj& obj)
{
obj.doSomething();
}
Еквівалент OOP буде чимось на зразок наступного коду Java:
public void foo(DoSomethingable obj)
{
obj.doSomething();
}
Основна відмінність, звичайно, полягає в тому, що версія Java вимагає створення інтерфейсу або ієрархії спадкування, перш ніж вона запрацює. Отже, версія Java передбачає більшу роботу та менш гнучка. Крім того, я вважаю, що більшість ієрархій успадкування в реальному світі є дещо нестабільними. Ми всі бачили надумані приклади "Фігур та тварин", але в реальному світі, коли вимоги бізнесу змінюються та додаються нові функції, важко виконати будь-яку роботу, перш ніж вам дійсно потрібно розтягнути відносини "є-а" між підкласи або іншим чином переробляти / рефакторувати вашу ієрархію, щоб включити подальші базові класи чи інтерфейси для задоволення нових вимог. Вводячи качок, вам не потрібно турбуватися про моделювання чогось - ви просто переживаєте про необхідну вам функціональність .
Однак успадкування та поліморфізм настільки популярні, що я сумніваюся, що це було б великим перебільшенням, щоб назвати їх домінуючою стратегією розширюваності та повторного використання коду. То чому ж успадкування та поліморфізм настільки диво успішні? Чи я не помічаю серйозних переваг, які мають успадкування / поліморфізм над типом качок?
obj
немаєdoSomething
методу? Чи піднято виняток? Нічого не відбувається?