Функціональне програмування проти об'єктно-орієнтованого програмування [закрито]


783

Я до цього часу в основному зазнавав програми програмування OO і з нетерпінням чекаю вивчення функціональної мови. Мої запитання:

  • Коли ви вибираєте функціональне програмування над об'єктно-орієнтованим?
  • Які типові визначення проблеми, коли функціональне програмування є кращим вибором?



1
подібне запитання cs.se також закрило, що є прикладом, коли функціональне програмування дає кращі результати, ніж імперативний стиль . Здається, що звичайна мудрість полягає в тому, що одна не перевершує інших, або вони не порівнянні за простими критеріями, або що вони використовуються для різних цілей ... , тож питання також встановлює нерозв'язний pov / конфлікт "галузь проти академії". одна класична реферат, яка демонструє
синдром

" OO робить код зрозумілим, інкапсулюючи рухомі частини. FP робить код зрозумілим, зводячи до мінімуму рухомі частини. " --Micheal Feathers, 2010
jaco0646

Відповіді:


1192

Коли ви вибираєте функціональне програмування на об'єктно-орієнтованому?

Коли ви передбачите розвиток еволюції програмного забезпечення:

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

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

Коли еволюція йде не так, у вас виникають проблеми:

  • Додавання нової операції до об'єктно-орієнтованої програми може потребувати редагування багатьох визначень класів, щоб додати новий метод.

  • Додавання нового виду до функціональної програми може потребувати редагування багатьох визначень функцій, щоб додати новий випадок.

Ця проблема добре відома вже багато років; У 1998 році Філ Вадлер назвав це "проблемою вираження" . Хоча деякі дослідники вважають, що проблему вираження можна вирішити за допомогою таких мовних особливостей, як міксин, загальновизнане рішення поки що не вплине на мейнстрім.

Які типові визначення проблеми, коли функціональне програмування є кращим вибором?

Функціональні мови досконалі в маніпулюванні символічними даними у вигляді дерева. Улюблений приклад - компілятори, де вихідні та проміжні мови змінюються рідко (переважно одні й ті ж речі ), але автори компіляторів завжди додають нові переклади та вдосконалення чи оптимізацію коду (нові операції над речами). Компіляція та переклад загалом - це "вбивчі програми" для функціональних мов.


119
За цією відповіддю стоїть якийсь серйозний дзен. Я думаю, що це висвітлює той факт, що певні шаблони дизайну OOP (Visitor) - насправді хаки, які намагаються подолати проблему додавання нових операцій.
Jacobs Data Solutions

54
У JavaScript ви можете мати всі речі.
Ерік Реппен

61
@ErikReppen, в який момент виникає питання, коли ви вирішите використовувати функціональні функції та коли ви вирішите використовувати об’єктно-орієнтовані функції?
Норман Рамзі

7
@NormanRamsey Це зовсім не рідкість, коли це змішується в JS, і функції першого класу пов'язані з багатьма функціями, пов'язаними з JS OOP. Сортування масиву JS приймає функції як аргумент, який може створювати деякі потужні структури даних. Закриття + передана функція використовується для збереження об'єктів jquery дуже легкої мови, оскільки мова йде про пам'ять, оскільки більшість методів є лише посиланнями. І т. Д ...
Ерік Відкрито

9
@NormanRamsey: Дуже хороша відповідь, згідно з принципом SICP. Відповідно до цієї класифікації функціональне та процедурне програмування групуються разом з протилежного боку об'єктно-орієнтованого програмування. Це може пояснити бум OOP в кінці 1980-х на початку 1990-х: коли графічні інтерфейси стали основними, OOP виявився хорошим підходом для моделювання їх, оскільки зазвичай у вас є фіксований набір операцій (фарба, відкривання, закриття, розмір) і зростаюча кількість віджетів. Звичайно, це не означає, що OOP кращий, ніж процедурний для будь-якої програми, як ви проілюстрували.
Джорджо

176

Не обов’язково вибирати між двома парадигмами. Ви можете писати програмне забезпечення з архітектурою ОО, використовуючи багато функціональних понять. FP і OOP мають ортогональний характер .

Візьмемо для прикладу C #. Можна сказати, що це переважно OOP, але існує багато концепцій та конструкцій ПП. Якщо розглядати Linq , найважливіші конструкції, які дозволяють Linq існувати, мають функціональний характер: лямбда-вирази .

Інший приклад, F #. Можна сказати, що це здебільшого FP, але є багато концепцій та конструкцій OOP. Ви можете визначити класи, абстрактні класи, інтерфейси, мати справу зі спадщиною. Ви навіть можете користуватися мутабельністю, коли це робить ваш код більш чітким або коли він різко підвищує продуктивність.

Багато сучасних мов є багатопарадигмою.

Рекомендовані читання

Оскільки я перебуваю в одному човні (фон OOP, навчання FP), я б запропонував вам кілька читань, які я дуже оцінив:


8
@duffymo: ваш коментар, як ви його висловлюєте, здебільшого безглуздий. Ніхто не хоче порівняння мов, віртуальних машин чи платформ, дякую.
Бруно Рейс

6
@Bruno - відповідь на "потужність .NET". Розслабтесь.
duffymo

6
Смішно, я не бачу, як ти надихаєш Дікама на його безглуздий коментар. Ви були призначені модератором, поки я не шукав? Тут ніхто не палає, крім вас. Скажу ще раз - розслабтесь.
duffymo

4
Хе, вибачте, якщо я почав палаючи. Я не хотів сказати, що інші платформи менш потужні, просто. NET не підтримує тільки OOP. Наприклад, він має оптимізацію хвостових викликів.
Дікам

5
@nawfal, поки ви не зможете вказати на деякі властиві у двох парадигмах і сказати, що вони несумісні, вони ортогональні: це серце дискусії. FP несумісний з імперативним програмуванням за визначенням, але OOP не обмежується імперативним програмуванням. Причина, що для цих понять у нас є різні слова, полягає в тому, що ми можемо говорити про них: коли ви їх згуртовуєте, ви просто змушуєте нас без потреби придумувати нові слова.
DavidS

31

Об'єктно-орієнтоване програмування пропонує:

  1. Інкапсуляція, до
    • контрольна мутація внутрішнього стану
    • обмеження зв'язку внутрішнього представництва
  2. Підгрупування, що дозволяє:
    • заміна сумісних типів (поліморфізм)
    • сирий спосіб розподілу реалізації між класами (успадкування реалізації)

Функціональне програмування в Haskell або навіть у Scala може дозволити заміщення через більш загальний механізм класів типів. Внутрішній стан, що змінюється, або знешкоджується, або забороняється. Також може бути досягнута інкапсуляція внутрішнього представництва. Дивіться Haskell vs OOP для хорошого порівняння.

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

EDITED Видалено посилання на неявні перетворення під час обговорення класів типів. У Scala класи типів кодуються неявними параметрами, а не перетвореннями, хоча неявні перетворення є ще одним засобом досягнення заміни сумісних типів.


3
Класи типу не є механізмом неявного перетворення в інші типи. Вони опис набору функцій, визначених для типу, щоб забезпечити форму поліморфізму. Найближчим із OOP у стилі Java - інтерфейси, хоча типи класів Haskell мають деякі важливі відмінності.
Зак

25
  1. Якщо ви перебуваєте в сильно одночасному середовищі, тоді корисне чисте функціональне програмування. Відсутність змінного стану робить паралельність майже тривіальною. Дивіться Ерланг.

  2. У мові мультипарадигми ви можете захотіти моделювати деякі функції функціонально, якщо існування змінного стану є детальною частиною реалізації, і, таким чином, FP є хорошою моделлю для проблемної області. Наприклад, див. Розуміння списку на Python або std.range у мові програмування D. Вони натхненні функціональним програмуванням.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.