Мой перевод, как и оригинальный доклад вызвали неоднозначную реакцию в комментариях. Поэтому я решил перевести статью-ответ дяди Боба на оригинальный материал.Множество программистов на протяжении последних лет утверждают, что ООП и ФП — являются взаимоисключающими. С высоты башни из слоновой кости в облаках, ФП-небожители иногда поглядывают вниз на бедных наивных ООП-программистов и снисходят до надменных комментариев. Приверженцы ООП в свою очередь косо смотрят на «функционыльщиков», не понимая, зачем чесать левое ухо правой пяткой.
Эти точки зрения игнорируют саму суть ООП и ФП парадигм. Вставлю свои пять копеек.
ООП не про внутреннее состояние
Объекты (классы) – не структуры данных. Объекты могут использовать структуры данных, но их детали реализации скрыты. Вот почему существуют приватные члены классов. Извне вам доступны только методы (функции), поэтому объекты про поведение, а не состояние.
Использование объектов в качестве структур данных – признак плохого проектирования. Инструменты, вроде Hibernate называют себя ORM. Это некорректно. ORM не отображают реляционные данные на объекты. Они отображают реляционные данные на структуры данных. Эти структуры – не объекты. Объекты группируют поведение, а не данные.
Думаю, здесь дядя Боб ругает ORM за то они часто подталкивают к анемичной модели, а не к богатой.Функциональные программы, как и объектно-ориентированные являются композицией функций преобразования данных. В ООП принято объединять данные и поведение. И что? Это действительно так важно? Есть огромная разница между
f(o), o.f()
и (f o)
? Что, вся разница в синтаксисе. Так в чем же настоящие различия между ООП и ФП? Что есть в ООП, чего нет в ФП и наоборот?ФП навязывает дисциплину в присвоение (immutability)
В «тру фп» нет оператора присвоения. Термин «переменная» вообще не применим к функциональным ЯП, потому что однажды присвоив значение его нельзя изменить.
Да. Да. Апологеты ФП часто указывают на то что функции – объекты первого класса. В Smalltalk функции – тоже объекты первого класса. Smaltalk – объектно-ориентированный, а не функциональный язык.
Ключевое отличие не в этом, а в отсутствии удобного оператора присваивания. Значит ли это, в ФП вообще нет изменяемого состояния? Нет. В ФП языках есть всевозможные уловки, позволяющие работать с изменяемым состоянием. Однако, чтобы сделать это, вам придется совершить определенную церемонию. Изменение состояния выглядит сложным, громоздким и чужеродным в ФП. Это исключительная мера, к которой прибегают лишь изредка и неохотно.
ООП навязывает дисциплину в работе с указателями на функции
ООП предлагает полиморфизм в качестве замены указателей на функции. На низком уровне полиморфизм реализуется с помощью указателей. Объектно-ориентированные языки просто делают эту работу за вас. И это здорово, потому что работать с указателями на функции напрямую (как в C) неудобно: всей команде необходимо придерживаться сложных и неудобных соглашений и следовать им в каждом случае. Обычно, это просто не реалистично.
В Java все функции виртуальные. Это значит, что все функции в Java вызываются не напрямую, а с помощью указателей на функции.
Если вы хотите использовать полиморфизм в C вам придется работать с указателями вручную и это сложно. Хотите полиморфизм в Lisp: придется передавать функции в качестве аргументов самостоятельно (кстати, это называется паттерном стратегия). Но в объектно-ориентированных языках все это есть из коробки: бери и пользуйся.
Взаимоисключающие?
Являются две эти дисциплины взаимоисключающими? Может ли ЯП навязывать дисциплину в присваивании и при работе с указателями на функции. Конечно может! Эти вещи вообще не связаны. Эти парадигмы – не взаимоисключающие. Это значит, что можно писать объектно-ориентированные функциональные программы.
Это также значит, что принципы и паттерны ООП могут использоваться и в функциональных программах, если вы принимаете дисциплину «указателей на функции». Но зачем это «функциональщикам»? Какие новые преимущества это им даст? И что могут получить объектно-ориентированные программы от неизменяемости.
Преимущества полиморфизма
У полиморфизма всего одно преимущество, но оно значительно. Это инверсия исходного кода и рантайм-зависимостей.
В болшинстве систем когда одна функция вызывает другую, рантайм-зависимости и зависимости на уровне исходного кода однонаправленны. Вызывающий модуль зависит от вызываемого модуля. Но в случае полиморфизма вызывающий модуль все еще зависит от вызываемого в рантайме, но исходный код вызываемого модуля не зависит от исходного кода вызываемого модуля. Вместо этого оба модуля зависят от полиморфного интерфейса.
Эта инверсия позволяет вызываемого модулю вести себя как плагину. Действительно, плагины так и работают. Архитектура плагинов крайне надежна, потому что стабильные и важные бизнес-правила могут храниться отдельно от подверженных изменениям и не столь важных правил.
Таким образом, для надежности системы должны применять полиморфизм, чтобы создать значимые архитектурные границы.
Преимущества неизменяемости
Преимущества неизменяемых данных очевидны – вы не столкнетесь с проблемами одновременных обновлений, если вы никогда ничего не обновляете.
Так как большинство функциональных ЯП не предлагает удобного оператора присвоения, в таких программах нет значительных изменений внутреннего состояния. Мутации зарезервированы для специфических ситуаций. Секции, содержащие прямое изменение состояния, могут быть отделены от многопоточного доступа.
Итого, функциональные программы гораздо безопаснее в многопоточной и многопроцессорной средах.
Занудные философствования
Конечно приверженцы ООП и ФП будут против моего редукционистского анализа. Они будут настаивать на том, что существуют значительные философские, филологические и математические причины, почему их любимый стиль лучше другого. Моя реакция следующая: Пфффф! Все думают, что их подход лучше. И все ошибаются.
Так что там про принципы и паттерны?
Что вызвало у меня такое раздражение? Первые слайды намекают на то что все принципы и паттерны, разработанные нами за десятилетия работы применимы только для ООП. А в ФП все решается просто функциями.
Вау, и после этого вы что-то говорите про редукционизм? Идея проста. Принципы остаются неизменными, независимо от стиля программирования. Факт, что вы выбрали ЯП без удобного оператора присвоения, не значит, что вы можете игнорировать SRP или OCP, что эти принципы будут каким-то образом работать автоматически. Если паттерн «Стратегия» использует полиморфизм, это еще не значит, что он не может применяться в функциональном ЯП (например Clojure).
Итого, ООП работает, если вы знаете, как его готовить. Аналогично для ФП. Функциональные объектно-ориентированные программы – вообще отлично, если вы действительно понимаете, что это значит.
Комментарии (65)
jakobz
18.09.2017 11:55-6Боб бы выглядел глуповатым гуманитарием, злобой и воинствующе пропагандирующим антинаучный образ мысли, и успешно зарабатывая продавая пухлые книжки ни о чём.
Если бы не одно но — они, напару с Фаулером, этот свой гуманитарный рак мозга, на целую индустрию распространили.AnutaU
18.09.2017 12:00+9Гуманитарии — это классные ребята, которые хорошо понимают в лингвистике, философии, истории, литературе и других соответствующих областях. Не понимаю, за что вы их так.
fillpackart
18.09.2017 12:53Видимо, имеется в ввиду, что им не следует писать о разработке. Хотя, конечно, к автору статьи это не относится
lair
18.09.2017 12:00+9Простите, а что конкретно гуманитарного вы видите в том, что пишут Мартин и Фаулер?
jakobz
18.09.2017 15:00Давай от противного. Что научного в том, что пишут Мартин и Фаулер? Понятие ООП — не определено формально. Свои утверждения они нигде и никогда никак не доказывают — ни методами естественных наук (статистические исследования), ни формально-математически.
Т.е. я открываю Фаулера, читаю что Rich лучше Anemic, но не вижу нигде даже попытки доказать почему. Есть график — типа Anemic на сложности загибается. Но откуда он его нарисовал, а? Да он его придумал из головы, когда писал книжку.
В этой статье — вообще софистика: автор переопределяет определения ООП и ФП как ему удобно, и начинает сравнивать только что выдуманные концепции.
Но там видно, что это он не со зла — он просто вообще не понимает чего несет, вот и всё.marshinov Автор
18.09.2017 15:08У него консалтинговая компания. Есть клиенты, вероятно собирают статистику. Если бы совсем не работало, наверное со временем его услугами перестали бы пользоваться. С моим опытом большинство утверждений Фаулера согласуются. Конкретные цифры конечно подтвердить не могу.
lair
18.09.2017 15:27+5Давай от противного. Что научного в том, что пишут Мартин и Фаулер?
Подождите, а я где-то утверждал, что работы Мартина и Фаулера научны? Я всего лишь спросил, почему вы считаете их гуманитарными.
RPG18
18.09.2017 17:45+1Самое лучшее из всех доказательств есть опыт.
Бэкон Ф
ни методами естественных наук (статистические исследования), ни формально-математически.
Проблема в том, что проводить статистические исследования в software engineering очень дорого, поэтому их особо никто не делает.
Nakosika
19.09.2017 09:36-5Я с вами полностью согласен, такой мути как эти ребята мало кто пишет. Но у Боба есть несколько хороших идей которые кочуют из статьи в статью, но не имея опыта читателю легко принять за чистую монету всякую кашу типа солида. Фаулер же рассуждает как новичок, прочитавший кучу книг по паттернам и судя по всему он вообще мало кодит, занимаясь консалтингом и преподаванием (развешиванием лапши).
А ведь таким умным можно себя считать почитав этих ребят, пока не увидишь на самом деле хороший код.
Жалко на хабре правдорубов жестко минусят, авось меньше заблуждений в обществе было бы.lair
19.09.2017 11:33+2Фаулер же рассуждает как новичок, прочитавший кучу книг по паттернам
… тот факт, что он написал книгу по паттернам, которую читают новички, вас не смущает?
Nakosika
19.09.2017 13:13Конечно смущает — большинство паттернов в современной разработке являются анти-паттернами, так как приводят к лавинообразному усложнению кода. Современная разработка сфокусирована на дата классах, иммутабельности и переиспользовании кода в функциональном стиле. Фаулер со своими паттернами ооп и анемичными классами выглядит просто нелепо. Он к стати недавно написал про датаклассы, но статью про анемичные классы так и не удалил, так что добро пожаловать в удивительный мир паттернов и чистого разума не имеющего отношения к современной разработке.
lair
19.09.2017 13:16+2Конечно смущает — большинство паттернов в современной разработке являются анти-паттернами, так как приводят к лавинообразному усложнению кода.
Вы, наверное, хотели сказать "при неправильном применении"? Потому что весь смысл паттерна в том, чтобы упростить код, решающий конкретную задачу.
(еще неплохо бы посмотреть на год написания PoEAA)
Современная разработка сфокусирована на дата классах, иммутабельности и переиспользовании кода в функциональном стиле.
Вот прямо вот вся? Откуда дровишки?
Фаулер со своими паттернами ооп и анемичными классами выглядит просто нелепо.
… или нет. Если понимать контекст утверждения.
Он к стати недавно написал про датаклассы, но статью про анемичные классы так и не удалил
А должен был? Анемичная доменная модель — это анемичная доменная модель, датаклассы — это датаклассы, зачем их путать?
Nakosika
19.09.2017 14:13-2Да почитайте вы Фаулера хоть прежде чем бросаться его защищать. martinfowler.com/bliki/CodeSmell.html
Да-да конечно, только при неправильном использовании паттерны приводят к проблемам. Рассказывайте это программистам которые пишут хелловорлды. В крупных проектах мутабельность (которая является неотъемлемым элементом большинства паттернов) приводит к лавинообразному росту багов, а связываение кода с данными (не дата классы) — это самый злостный противник рефакторинга.
Поработайте в командах от 30-и программистов с агайлом и скрамами, чтобы прочувствовать всю глубину говнокода который можно намаслать со всякими умными паттернами. Такой опыт немного отрезвляет и спускает с облаков с радугами, пони, Фаулером и Бобом, солидом и оопаттернами.
Ну есть конечно и такие которые не могут делать выводы, за такими постоянно няньки с тряпками ходят и подтирают. Для них баги появляются сами по себе, а святой Фаулер, конечно же, ни в чем не виноват, ведь он, ах-ах, книгу написал.vintage
19.09.2017 14:28+1мутабельность приводит к лавинообразному росту багов
Не мутабельность, а неидемпотентность.
asoukhoruchko
19.09.2017 14:46+2Для каких паттернов мутабельность является неотъемлимым свойством?
Как SOLID мешает вам писать нормальный код в средненькой по размеру команде?
Почему вы считаете, что только у вас есть опыт работы в такой ситуации — или что он у всех отрицательный?Nakosika
19.09.2017 17:34-1Визитор, итератор, мвп итп.
Мне никак солид не мешает, я на него ложил. Или клал, я хз как сегодня правильно. Просто его определение слишком размыто для практического применения.
Я так не считаю. Отрицательный он судя по тому что я вижу. Надежность в ООП достигается в результате сверхусилий и такой код крайне трудно рефачить в сравнении с подходом, который я описал выше.lair
19.09.2017 17:51Надежность в ООП достигается в результате сверхусилий и такой код крайне трудно рефачить в сравнении с подходом, который я описал выше.
Здесь, наверное, стоит уточнить: "надежность в ООП вами достигается в результате сверхусилий, и такой код вам крайне трудно рефакторить", да?
Nakosika
19.09.2017 18:40Нет, не стоит. К таким выводам пришли большинство известных мне разработчиков, которые знают больше чем ооп.
А вы знаете хоть один фп язык? Или ходите только тыкаете людей что они ооп плохо знают раз у них с ним проблемы? И чем фп хуже исходя из вашего богатейшего опыта?lair
19.09.2017 18:42Нет, не стоит. К таким выводам пришли большинство известных мне разработчиков, которые знают больше чем ооп.
Окей, заменяем "вами/вам" на "большинством/большинству известных вам разработчиков". Так правильно?
А вы знаете хоть один фп язык?
Да.
И чем фп хуже исходя из вашего богатейшего опыта?
А я где-то говорил, что ФП чем-то хуже?
asoukhoruchko
19.09.2017 17:59Visitor — описывает процесс, который не подразумевает мутабельного состояния. Если оно вам необходимо, вы его инкапсулируете, и отдаёте только по результатам работы. Можете его сделать даже иммутабельным, никто не мешает.
Iterator — какую его часть вы называете мутабельным состоянием? А, главное, как вы к нему хотите получить доступ?
MVP — как вы пишете иммутабельный UI, расскажите пожалуйста.
Ну и размытое определение SOLID это пять.
lair
19.09.2017 15:01+1Да почитайте вы Фаулера хоть прежде чем бросаться его защищать
Вообще-то, я достаточно много его читал. И что?
Да-да конечно, только при неправильном использовании паттерны приводят к проблемам.
Да, именно так. Приведите мне пример правильного использования паттерна, при котором возникает проблема.
В крупных проектах мутабельность (которая является неотъемлемым элементом большинства паттернов) приводит к лавинообразному росту багов, а связываение кода с данными (не дата классы) — это самый злостный противник рефакторинга.
Давайте откажемся от ООП, для которого мутабельность и связывание кода с данными — основополагающие свойства (окей, не неотъемлимые, но существенные)?
Поработайте в командах от 30-и программистов с агайлом и скрамами, чтобы прочувствовать всю глубину говнокода который можно намаслать со всякими умными паттернами.
Поработайте в той же команде, чтобы понять всю глубину говнокода, который можно намаслать со всякими умными компьютерами. Компьютеры на выброс, да?
У меня начинает создаваться ощущение, что вы не вполне понимаете, что такое, собственно, паттерн в программировании (те, которые Design Pattern). Как вы это определяете?
jakobz
19.09.2017 16:00-1>Давайте откажемся от ООП
Если что, все давно уже отказались от ООП в том виде, в котором он изначально продавался — где белочки от зайчиков наследуются, а счета Алисы и Боба — отдельные объекты.
Сейчас ходу подход на смеси ФП и процедурного программирования — stateless-сервисы колбасят DTO-шки. Да, формально это ООП — т.к. под определение «все есть объект» подходит вообще всё. Но индустрия давно переболела идеями типа Rich Data Model. По факту ООП там-сям имеется, но концептуально идея ООП — давно провалилась с треском.
А апологеты ООП, типа Боба и Фаулера, спасаются тем, что переименовывают идеи из ФП в свой птичий язык, и говорят что всё это — они придумали, и все это до сих пор — ООП. Хотя всем уже давно пора убрать этих посредников, и выйти в мир, где есть масса крутых концепций, а не только то, что на свой птичий язык перевел Фаулер.
Посмотри тот же SICP — там про ООП только одна глава из пары десятков. Вот эти 20 раз — это как раз тот порядок, на который ООП-шники ограничивают свой кругозор.lair
19.09.2017 16:47+1Если что, все давно уже отказались от ООП в том виде, в котором он изначально продавался — где белочки от зайчиков наследуются, а счета Алисы и Боба — отдельные объекты.
… а где вы взяли такое ООП? Я его никогда не видел.
Но индустрия давно переболела идеями типа Rich Data Model. По факту ООП там-сям имеется, но концептуально идея ООП — давно провалилась с треском.
А можно увидеть обоснование для этого громкого утверждения?
Хотя всем уже давно пора убрать этих посредников, и выйти в мир, где есть масса крутых концепций, а не только то, что на свой птичий язык перевел Фаулер.
А кто-то где-то говорил, что надо читать только Фаулера?
asoukhoruchko
19.09.2017 17:44Из моей практики то, о чём вы говорите — было верно на 2010 год. Тогда в ходу действительно была в основном анемичная модель Кстати, по моим воспоминаниям Фаулер в своём PoEA вполне себе описывал целиком ту модель, которую вы сейчас с восторгом описываете. Это 2002 год, если что.
Я бы сказал, что именно в последние пару-тройку лет Rich Data Model снова начала набираться популярность, на фоне всяких Domain Driven Design и прочих радостей. Просто то же DDD советуют применять только если у вас высоко профессиональная команда, иначе придётся собирать грабли.
Хотя у того же Фаулера подходы без использования RICH
michael_vostrikov
19.09.2017 19:35Хотя всем уже давно пора убрать этих посредников, и выйти в мир, где есть масса крутых концепций
20 раз — это как раз тот порядок, на который ООП-шники ограничивают свой кругозор.Вот есть игра в дурака, написана в ООП стиле. Сможете переписать ее с использованием крутых концепций ФП и 20 глав расширенного кругозора? Я серьезно, просто интересно сравнить результат и оценить сложность кода и дальнейшей поддержки.
rraderio
19.09.2017 16:10-1Приведите мне пример правильного использования паттерна, при котором возникает проблема.
Singleton это паттерн или анти-паттерн?lair
19.09.2017 16:45+1Зависит от использования, конечно же. С тех пор, как управление зависимостями стало принято переносить наружу, реализация синглтона изменилась с той, которая описана в GoF, на "делегируйте ответственность в DI".
rraderio
19.09.2017 18:12Приведите мне пример правильного использования паттерна, при котором возникает проблема.
Т.е. DI делает Singleton анти-паттерном?
Т.е. нет гарантии что завтра будет новый паттерн который сделает анти-паттернами сегодняшние паттерны?lair
19.09.2017 18:17Т.е. DI делает Singleton анти-паттерном?
Нет, неуместное использование делает синглтон антипаттерном.
Т.е. нет гарантии что завтра будет новый паттерн который сделает анти-паттернами сегодняшние паттерны?
Конечно, нет. Индустрия развивается.
asoukhoruchko
19.09.2017 16:45+1Это инструмент.
И паттерн — поскольку это повторяющийся элемент проектирования.
Но из-за узких границ применимости, и нежелания людей думать, его долго пихали в те места, где он плохо работает.
А поскольку думать большинству по-прежнему лень, его «признали плохим».
Микроскоп, кстати, тоже негодная вещь — ей гвозди неудобно заколачивать.lair
19.09.2017 16:49Кстати, да, соглашусь. Синглтон — паттерн, вне зависимости от использования (вопреки тому, что я выше написал), просто зона его корректной применимости меньше, чем многие думают.
rraderio
19.09.2017 18:18просто зона его корректной применимости
И какие применимости у Синглтона?lair
19.09.2017 18:24Проекты, не имеющие системы управления зависимостями, или ситуации, когда на конкретный объект не распространяются существующие правила управления зависимостями. Приведенный ниже пример с
EqualityComparer<T>.Default
— очень хорош.
Более того, если рассматривать синглтон как поведение, а не как реализацию, то все реализации через произвольный внешний менеджер (в том числе — DI-контейнер) тоже становятся валидными.
asoukhoruchko
19.09.2017 18:25+1Та же, что и раньше.
В ситуации, когда изначально предложенная имплементация начинает вам мешать, его стоит заменить на что-то другое.
Например, в небольших домашних проектах использовать синглтон гораздо разумнее, чем пихать туда DI в каком-либо виде.
mayorovp
19.09.2017 17:05+2У этого слова несколько значений, одно из них — порождающий паттерн. Сфера его правильного использования — объекты, не имеющие своих зависимостей в принципе, которые должны существовать в единственном экземпляре либо по архитектурным причинам, либо для экономии памяти.
При неумеренном использовании легко превращается в анти-паттерн.
Пример нормального синглтона в стандартной библиотеке C# —
EqualityComparer<T>.Default
. Реализация интерфейсаIEqualityComparer<T>
по умолчанию, использующая методEquals
, по возможности без боксинга. При этом у того же самого интерфейса возможны и иные реализации, не являющиеся синглтонами.
lair
19.09.2017 12:11+1Жалко на хабре правдорубов жестко минусят
Ой, да. "Минусят" не "правдорубов", а тех, кто никак не аргументирует свою точку зрения.
andreyverbin
19.09.2017 12:11+3Проблема не в том, что дядя Боб и Фаулер антинаучные, проблема в том, что в области проектирования софта вообще ничего научного нет. Это черная магия, что-то происходит в голове проектировщика и он говорит — тут будет «фабрика». Оптимальность этого решения оценить нельзя. Показать, что это решение лучше чем другое, тоже затруднительно.
Как следствие применимость идей дяди Боба и Фаулера к конкретной системе оценить не получится. Результаты будут любыми, иногда хорошими и тогда авторов будут хвалить, иногда плохими и тогда будут ругать себя.Nakosika
19.09.2017 22:55-1Так никто не пытается сделать его научным. Бродят всякие авторитеты и надувают щеки, книги пишут. Я всего пару статей видел как кто-то пытался осмыслить такие концепты как состояние и процедура. Народ заносит в какую-то дикую математику или гуманитарщину. Им сказали тридцать лет назад что серебряной пули нет, так они и не стараются ее найти. Как Кант сказал что ничего понять невозможно, так философы и перестали думать, у нас то же самое.
А тем временем новые эффективные концепты приходят на смену старому барахлу, казалось бы подумай, пойми почему одно лучше другого, напиши статью, двинь талк, экстраполируй, сформулируй закон или хотя бы теорему… Просто крутые профессионалы типа Рича Хики на фоне современных ученых из компьютер саенц гениями выглядят, просто потому что они сели и подумали прежде чем что-то лепить.lair
19.09.2017 23:26+2Народ заносит в какую-то дикую математику или гуманитарщину.
… а вы что под "гуманитарщиной" понимаете?
А тем временем новые эффективные концепты приходят на смену старому барахлу, казалось бы подумай, пойми почему одно лучше другого, напиши статью, двинь талк, экстраполируй, сформулируй закон или хотя бы теорему…
А те, кто эти "эффективные конь-цепты" принес — они сформулировали закон или теорему? Подвели научное обоснование?
Nakosika
20.09.2017 11:43-3Мы уже увидели в соседнем обсуждении, что вы не читаете источники и ходите критикуете тех кто читал. Поучитесь уж чему-то чтобы не задавать вопросы ответы на которые все знают.
lair
20.09.2017 11:48+1(Казалось бы, какое отношение это имеет к вопросу "что вы понимаете под "гуманитарщиной""...)
Мы уже увидели в соседнем обсуждении, что вы не читаете источники и ходите критикуете тех кто читал.
Когда критикуют высказывание, не важно, что читал человек, важно, что он сказал.
Поучитесь уж чему-то чтобы не задавать вопросы ответы на которые все знают.
"Все знают" ответ на вопрос "что вы понимаете под гуманитарщиной"? Или "все знают" ответ на вопрос "подвели ли научное обоснование те, кто принес в программирование новые эффективные концепты на смену старому барахлу"? Если второе, то может быть вы мне приведете хотя бы пяток примеров? Мне всегда было интересно, что такое "научное обоснование в software design".
vintage
18.09.2017 12:25+2Стоит отметить, что thread local storage и type attributes (shared) позволяют точно так же отделить многопоточный доступ в "отдельные секции", не теряя возможностей ООП. И наоборот function attributes (pure) позволяют получить гарантии чистых функций, реализуя их совсем не ФП способом с присваиваниями и прочим.
napa3um
18.09.2017 13:26+5Мне кажется, что парадигмы ООП и ФП — это способы мышления над прикладной задачей, полезные обе вне зависимости от используемого языка программирования.
ООП удобен для описания сущностей прикладной задачи и сущностей «вычислителя», на котором задача будет моделироваться, для декомпозиции прикладной задачи и вычислителя на максимально независимые модели состояния (чем ближе объект к «голой» структуре, чем меньше у него сложных методов трансформации — тем лучше, декларативнее). ФП же удобен для декомпозиции решения этой задачи в максимально независимые функции. Грубо говоря, в ООП-стиле удобно описывать «Дано» и «Надо», а в ФП-стиле — «Решение». Обе парадигмы полезны и в абсолюте неразделимы, потому в той или иной степени поддерживаются любым практическим языком программирования, но с «перекосом» в ту или иную сторону. И выбор языка, как мне кажется, зависит от выбранной методологии разработки и ценности полученного решения. Если хочется идти сверху вниз, от абстрактного решения к низкоуровневым аспектам реализации, и именно «решение» является максимально сложным и ценным аспектом в разрабатываемой инфосистеме, то выбирают что-то из «ФП-сильных» языков. Если же хочется идти снизу вверх, если «решение» как таковое тривиально и заранее известно, если инфосистема несёт ценность в большей степени как проецирование бизнеса («дано и надо») на «кремний», то выбирают «ООП-сильный» язык.
nomoreload
18.09.2017 13:37+1Прочитал ObjectOriented VisualStudio FunctionalProgramming. ASP.NET головного мозга, блин)
andreyverbin
18.09.2017 13:46+2Мне больше нравится точка зрения на FP vs OOP описанная в SICP, где OOP рассматривается как способ достичь модульности путем сокрытия состояния. Того же можно добиться и в FP, например, в Haskell можно сделать что-то вроде
class MyClass state where myMethod :: (MyClass state) => state -> state
В этом случае разница между OOP и FP заключается только в неизменяемых данных. А если вспомнить OCaml, который функциональный, но данные в нем менять можно, то вопрос о OOP vs FP как-то вообще теряет смысл.
Bonart
18.09.2017 14:47+5Использование объектов в качестве структур данных – признак плохого проектирования.
Дядюшка Боб традиционно впадает в
маразмдогматизм.
Структура данных — частный случай объекта, чье ожидаемое поведение как раз хранить и давать доступ к данным.
Инструменты, вроде Hibernate называют себя ORM. Это некорректно. ORM не отображают реляционные данные на объекты. Они отображают реляционные данные на структуры данных. Эти структуры – не объекты. Объекты группируют поведение, а не данные.
Логичное продолжение из неверной исходной посылки. Реляционная модель сильно отличается от объектной, поэтому отображение возможно лишь для ограниченного подмножества объектов. Его ORM и реализуют.
Первые слайды намекают на то что все принципы и паттерны, разработанные нами за десятилетия работы применимы только для ООП. А в ФП все решается просто функциями.
Многие паттерны из ООП действительно не имеет смысла специально обсуждать для ФП, так как они имеют там тривиальное готовое решение.
Кстати, верно и обратное: изменяемое состояние для ФП — паттерн, а для ООП о нем как о паттерне говорить особого смысла нет.
Аналогично "виртуальный метод" — паттерн для процедурных языков, но для ООП уже есть простое готовое решение.marshinov Автор
18.09.2017 16:16-1Аналогично «виртуальный метод» — паттерн для процедурных языков, но для ООП уже есть простое готовое решение.
А, в ФП некоторые фичи встроенные в язык заменяют ООП-паттерны (стратегия, декоратор).
Не смотря на свойственную Мартину сварливость в статье есть коротко-сформулированный и важный тезис: ФП и ООП — вещи не взаимоисключающие, а наоборот — дополняющие.
asoukhoruchko
20.09.2017 15:10«Объект без поведения» это структура данных, потому что единственный его смысл это хранить данные.
ООП выросло из структурного программирования, и задачей появления объектов было получить управляющую структуру. Т.е. объект нужен, чтобы поддерживать нечто (например, структуру данных) в непротиворечивом состоянии.
Исходя из этого структура данных может являться объектом физически (в терминах C# или Java), но логически это структура данных. Т.е. нормально сконструированный объект должен быть консистентным, а структура данных такого ограничения не имеет.
vbif
18.09.2017 15:41-3Мне кажется, что одна из причин популярности ООП — удобство работы с IDE. Набрал название переменной, ставишь точку и нажимаешь ctrl+space — он показывает, что с этим можно сделать.
rraderio
18.09.2017 16:08+3number |> и нажимаешь ctrl+space
vbif
18.09.2017 18:49Речь не о том, что в ФП это сделать нельзя, а о том, что в прежних не-ОО языках так просто нельзя было сделать, а с ООП стало можно, и потому все начали массово переходить на ОО-языки.
vsapronov
19.09.2017 09:07Со всем уважением, но это в какой IDE вот это вот |> ctrl + space у вас хорошо работает для какого языка. Уж не про F# с VS вы говорите?
Я не поддерживаю точку зрения комментатор: конечно ООП-ФП это не про IDE. Однако, инструментарий очень важен для компаний. Поэтому интересуюсь…
potan
18.09.2017 16:09-2«Функциональные программы, как и объектно-ориентированные являются композицией функций преобразования данных. В ООП принято объединять данные и поведение. И что? Это действительно так важно?» — за этим вопросом следует параграф про иммутабельность, где разясняется, почему это действительно выжно. Пока состояние инкапсулировано в поведении об иммутабельности речи идти не может.
AnutaU
Можно, я ещё разок оставлю эту ссылку?
Кстати, почему автор говорит так, будто в ФП нет полиморфизма?
marshinov Автор
Судя по всему, потому что для дяди Боба полиморфизм — это прежде всего удобство не возиться с указателями. Думаю, чтобы прочувствовать эту точку зрения, нужно написать много кода на чистом C.
AnutaU
Так-то понятно, что он имел в виду. Но зря не уточнил, как мне кажется. Особенно странно выглядит на фоне сравнения с динамически-типизированными языками, где полиморфизм (в смысле применения одного и того же кода к объектам разного типа) получается сам.
Nakosika
Зависит от языка. В кложуре к примеру не было. Там вообще типов нет, есть что-то типа свича на паттерн матчинге. Там это гордо называют полиморфизмом, но к классической дефиниции полиморфизма (запуск разных функций в зависимости от типа данных) это отношения мало имеет. Настоящий полиморфизм там сделан через интерфейсы (протоколы) но эта фича там недавно появилась.
AnutaU
Не знаю, будет ли для вас это определение достаточно классическим, но я его не сама придумала, а взяла из книжки Б. Пирса «Типы в языках программирования» (перевод на русский, с. 354):
Термин полиморфизм (polymorphism) обозначает семейство различных механизмов, позволяющих использовать один и тот же фрагмент программы с различными типами в различных контекстах.
У вас же та же самая ошибка, что и у дяди Боба в статье: вы считаете только один из видов полиморфизма «настоящим». То, какой именно полиморфизм дядя Боб имеет в виду, понятно из контекста, так что это больше занудство. Но то, что он это не уточнил, глаз сразу режет.
Звучит примерно как «да у них денег нет, они карточкой заплатят». Есть в Clojure типы, просто они не проверяются статически.
Nakosika
Это вы тоже самое мне сказали про полиморфизм что и я, только со с точки зрения пользователя полиморфизма а не реализации.
Конечно в кложуре есть типы, я имел в виду статические конечно же, неправду написал, извиняюсь. Но полиморфизм основанный на типах там не с первой версии. Там сначала был только на тэгах, если не ошибаюсь опять.