Сообщение в блоге, которое вы цитировали, немного переоценивает его утверждение. FP не устраняет необходимость в шаблонах проектирования. Термин «шаблоны проектирования» просто широко не используется для описания того же в языках FP. Но они существуют. Функциональные языки имеют множество правил наилучшей практики в форме «когда вы сталкиваетесь с проблемой X, используйте код, похожий на Y», который в основном представляет собой шаблон проектирования.
Тем не менее, верно, что большинство специфичных для ООП шаблонов проектирования в функциональных языках практически не имеют значения.
Я не думаю , что это должно быть особенно спорным , чтобы сказать , что дизайн модели в целом существуют только заделать недостатки в языке. И если другой язык может решить эту проблему тривиально, этому другому языку не понадобится шаблон проектирования. Пользователи этого языка могут даже не знать, что проблема существует , потому что, ну, это не проблема на этом языке.
Вот что говорит Банда Четырех по этому вопросу:
Выбор языка программирования важен, потому что он влияет на точку зрения. Наши шаблоны предполагают особенности языка уровня Smalltalk / C ++, и этот выбор определяет, что можно, а что нельзя легко реализовать. Если бы мы предполагали процедурные языки, мы могли бы включить шаблоны проектирования, называемые «Наследование», «Инкапсуляция» и «Полиморфизм». Точно так же некоторые из наших шаблонов поддерживаются непосредственно менее распространенными объектно-ориентированными языками. Например, CLOS имеет несколько методов, которые уменьшают потребность в шаблоне, таком как Visitor. На самом деле, между Smalltalk и C ++ достаточно различий, чтобы означать, что некоторые шаблоны могут быть выражены легче на одном языке, чем на другом. (См. Итератор для примера.)
(Выше приведена цитата из книги «Введение в шаблоны проектирования», стр. 4, абзац 3).
Основные функции функционального программирования включают функции как первоклассные значения, карри, неизменяемые значения и т. Д. Мне не кажется очевидным, что шаблоны проектирования ОО приближаются к любой из этих функций.
Что такое шаблон команды, если не аппроксимация функций первого класса? :) На языке FP вы просто передаете функцию в качестве аргумента другой функции. В языке ООП вы должны заключить функцию в класс, который вы можете создать, а затем передать этот объект другой функции. Эффект тот же, но в ООП он называется шаблоном проектирования и требует гораздо больше кода. А что такое абстрактный шаблон фабрики, если не карри? Поочередно передавайте параметры функции, чтобы настроить, какое значение она выдает, когда вы, наконец, вызываете ее.
Так что да, некоторые шаблоны проектирования GoF представляются избыточными в языках FP, потому что существуют более мощные и простые в использовании альтернативы.
Но, конечно, есть еще шаблоны проектирования, которые не решаются языками FP. Что такое эквивалент FP синглтона? (На мгновение не обращая внимания на то, что использование синглетонов - это, как правило, ужасный шаблон.)
И это работает в обе стороны тоже. Как я уже сказал, у FP тоже есть свои шаблоны проектирования; люди просто не думают о них как таковые.
Но вы могли наткнуться на монады. Каковы они, если не шаблон дизайна для "работы с глобальным состоянием"? Это проблема, которая настолько проста в языках ООП, что не существует эквивалентного шаблона проектирования.
Нам не нужен шаблон проектирования для «увеличения статической переменной» или «чтения из этого сокета», потому что это именно то, что вы делаете .
Сказать, что монада - это шаблон проектирования, так же абсурдно, как сказать, что целые числа с их обычными операциями, а нулевой элемент - это шаблон проектирования. Нет, монада - это математическая модель , а не модель дизайна.
В (чистых) функциональных языках побочные эффекты и изменяемое состояние невозможны, если вы не работаете с ним с помощью «шаблона проектирования» монады или какого-либо другого метода, разрешающего то же самое.
Кроме того, в функциональных языках, которые поддерживают ООП (таких как F # и OCaml), мне кажется очевидным, что программисты, использующие эти языки, будут использовать те же шаблоны проектирования, которые доступны для любого другого языка ООП. Фактически, сейчас я использую F # и OCaml каждый день, и нет никаких разительных отличий между шаблонами, которые я использую в этих языках, и шаблонами, которые я использую, когда пишу на Java.
Возможно, потому что ты все еще думаешь настоятельно? Многие люди, всю жизнь имея дело с императивными языками, с трудом отказываются от этой привычки, когда пытаются использовать функциональный язык. (Я видел несколько довольно забавных попыток в F #, где буквально каждая функция была просто строкой операторов let), в основном, как если бы вы взяли программу на C и заменили все точки с запятой на «let». :))
Но другая возможность может заключаться в том, что вы просто не поняли, что решаете проблемы тривиально, для чего потребуются шаблоны проектирования на языке ООП.
Когда вы используете каррирование или передаете функцию в качестве аргумента другой, остановитесь и подумайте, как бы вы сделали это на языке ООП.
Есть ли правда в утверждении, что функциональное программирование устраняет необходимость в шаблонах проектирования ООП?
Ага. :) Когда вы работаете на языке FP, вам больше не нужны специфичные для ООП шаблоны проектирования. Но вам все еще нужны некоторые общие шаблоны проектирования, такие как MVC или другие, не относящиеся к ООП, вещи, и вместо этого вам понадобится пара новых специфических для FP «шаблонов проектирования». У всех языков есть свои недостатки, и шаблоны проектирования обычно таковы, как мы их обходим.
В любом случае, вам может быть интересно попробовать свои силы в «более чистых» языках FP, таких как ML (мой личный фаворит, по крайней мере, в учебных целях), или Haskell , где у вас нет костыля ООП, к которому можно прибегнуть, когда вы столкнулись с чем-то новым.
Как и ожидалось, несколько человек возразили против моего определения шаблонов проектирования как «исправление недостатков в языке», поэтому вот мое оправдание:
Как уже говорилось, большинство шаблонов проектирования специфичны для одной парадигмы программирования, а иногда даже для одного конкретного языка. Часто они решают проблемы, которые существуют только в этой парадигме (см. Монады для FP или абстрактные фабрики для ООП).
Почему абстрактный шаблон фабрики не существует в FP? Потому что проблемы, которую он пытается решить, там не существует.
Таким образом, если существует проблема в языках ООП, которой нет в языках FP, то ясно, что это недостаток языков ООП. Проблема может быть решена, но ваш язык этого не делает, но для ее решения вам понадобится куча шаблонного кода. В идеале, мы бы хотели, чтобы наш язык программирования волшебным образом устранял все проблемы. Любая проблема, которая все еще существует, в принципе является недостатком языка. ;)