Лекция
Привет, Вы узнаете о том , что такое недостатки ооп, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое недостатки ооп, альтернатива ооп, ddd, архитектура программного обеспечения , настоятельно рекомендую прочитать все из категории Объектно-ориентированное программирование ООП.
Объектно-ориентированное программирование — чрезвычайно плохая идея, которая могла возникнуть только в Калифорнии.
— Эдсгер Вибе Дейкстра
Объектно-ориентированные программы предлагаются в качестве альтернативы правильным.
Эдсгер В. Дейкстра, пионер информатики
Объектно-ориентированное программирование было создано с одной целью — управлять сложностью процедурных кодовых баз. Другими словами, такой подход должен был улучшить организацию кода. Нет объективных и открытых доказательств того, что ООП лучше простого процедурного программирования или функционального или логического программирования.
«Объектно-ориентированные программы предложены как альтернатива правильным...»
– Эдсгер Вибе Дейкстра, один из разработчиков концепции структурного программирования.
Объектно-ориентированное программирование создавалось с одной целью: управление сложностью процедурного кода. Другими словами, оно должно было улучшить организацию кода. Между тем, не существует объективного и открытого доказательства превосходства ООП над чистым процедурным программированием.
Горькая правда состоит в том, что ООП терпит неудачу в единственной поставленной ему задаче. Оно выглядит хорошо на бумаге, где у нас чистые иерархии животных, собак, людей и так далее. Все это рушится по мере роста сложности приложения. Вместо понижения сложности оно поощряет беспорядочное совместное использование изменяемого состояния и вносит дополнительную сложность с его многочисленными шаблонами проектирования. ООП усложняет рефакторинг и тестирование.
Многие не согласятся, но правда в том, что современное ООП никогда не разрабатывалось правильно. Оно никогда не опиралось на правильные исследовательские институты (в отличие от Haskell/FP). У ООП нет десятилетий строгих научных исследований. Лямбда-исчисления предлагают полную теоретическую основу для функционального программирования. У ООП нет ничего близкого к этому. По большому счету, ООП «просто случилось».
ООП-код недетерминированный, в отличие от функционального программирования нам не гарантирован одинаковый вывод при одном и том же вводе. В качестве упрощенного примера: 2 + 2 или calculator.Add(2, 2) дают на выходе 4, но иногда могу дать 3, 5 или вообще 1004. Зависимости объекта Calculator могут менять результат вычислений в тонкой, но глубокой манере.
Объектно-ориентированное программирование кажется стандартной, самой распространенной парадигмой проектирования ПО. Именно его обычно преподают студентам, объясняют в онлайн-туториалах и, по какой-то причине, спонтанно применяют даже тогда, когда не собирались этого делать.
Я знаю, насколько она привлекательна, и какой замечательной кажется эта идея на поверхности. На разрушение ее чар у меня ушли многие годы, и теперь я понимаю, насколько она ужасна, и почему. Благодаря этой точке зрения у меня есть четкая уверенность в том, что люди должны осознать ошибочность ООП и знать решения, которые можно использовать вместо него.
Вспомним что такое ООП, которому уже более 50 лет.
Тимоти Бадд пишет:
Роджер Кинг аргументированно настаивал, что его кот является объектно-ориентированным. Кроме прочих своих достоинств, кот демонстрирует характерное поведение, реагирует на сообщения, наделен унаследованными реакциями и управляет своим, вполне независимым, внутренним состоянием.
По мнению Алана Кэя, создателя языка Smalltalk, которого считают одним из «отцов-основателей» ООП, объектно-ориентированный подход заключается в следующем наборе основных принципов (цитируется по вышеупомянутой книге Т. Бадда).
- Все является объектом.
- Вычисления осуществляются путем взаимодействия (обмена данными) между объектами, при котором один объект требует, чтобы другой объект выполнил некоторое действие. Объекты взаимодействуют, посылая и получая сообщения. Сообщение — это запрос на выполнение действия, дополненный набором аргументов, которые могут понадобиться при выполнении действия.
- Каждый объект имеет независимую память, которая состоит из других объектов.
- Каждый объект является представителем класса, который выражает общие свойства объектов (таких, как целые числа или списки).
- В классе задается поведение (функциональность) объекта. Тем самым все объекты, которые являются экземплярами одного класса, могут выполнять одни и те же действия.
- Классы организованы в единую древовидную структуру с общим корнем, называемую иерархией наследования. Память и поведение, связанное с экземплярами определенного класса, автоматически доступны любому классу, расположенному ниже в иерархическом дереве.
Таким образом, программа представляет собой набор объектов, имеющих состояние и поведение. Объекты взаимодействуют посредством сообщений.
Многие люди и раньше обсуждали проблемы ООП, и в конце этого поста я приведу список своих любимых статей и видео. Но прежде я хочу поделиться собственным взглядом.
«Мне очень жаль, что я давно ввел термин "объекты" для этой темы, потому что он заставляет многих людей сосредоточиться на меньшей идее. Основная идея – обмен сообщениями.» – Алан Кэй, один из пионеров в областях объектно-ориентированного программирования.
Алан Кэй придумал термин «Объектно-ориентированное программирование» а 1960х. Благодаря своему биологическому бэкграунду он пытался создать коммуникацию между компьютерными программами по подобию живых клеток.
Основная идея Алана Кэя состояла в коммуникации между независимыми программами (клетками). Состояние независимых программ никогда не раскрывалось внешнему миру (инкапсуляция).
Вот и все. ООП никогда не было предназначено для таких вещей, как наследование, полиморфизм, ключевого слова «new» и несчетного количества шаблонов проектирования.
«C++ – ужасный [объектно-ориентированный] язык... Ограничение вашего проекта до C означает, что люди не облажаются с какой-нибудь идиотской "объектной моделью"c&@p.» – Линус Торвальдс, создатель Linux.
Линус Торвальдс известен своей критикой в адрес C++ и ООП. Он прав в ограничении программистов. Чем меньше выбора у программиста, тем гибче становится его код. В цитате выше Линус Торвальдс настоятельно рекомендует использовать хороший фреймворк как базу для кода.
Многим не нравятся знаки ограничения скорости на дороге, но они необходимы для предотвращения несчастных случаев. Хороший фреймворк должен также предотвращать глупые действия.
Хороший фреймворк помогает писать надежный код. Он должен помогать снижать сложность с помощью:
К несчастью, ООП предоставляет разработчикам слишком много инструментов без ограничений. Даже если ООП обещает обратиться к модульности и улучшению повторного использования, ему не удается выполнить обещания (далее подробней). ООП-код поощряет использование общих изменяемых состояний, которые снова и снова доказывают свою небезопасность.
Еслибы вы были владельцем проекта ,то как бы вы ранжировали(упорядочили ) такие понятия для вашего проекта?
Для классичческого ООП будет примерно такая последовательность и важность
1 место e)
2 место d)
3 место c)
4 место b)
5 место a)
Взляните на эту иерархию(примечание, нельзя на одном месте ставить несколко понятий), вы заметили что при слепом применении ООП вы просто плюете на саму идею приложения и заказчика? теперь задумайтесь нужно ли слепо применять ООП и все ли у него хорошо?
Ктому не следует забывать что все императивные языки программирования и парадигмы (включая ООП) более примитивные по сравнению с декларативным программированием (включая Языково-ориентированное программирование, DSL-Based Development, предметно-ориентированных языков ) Примерами языков и парадигм с более высоким уровнем и более современными являются функциональные языки программирования, SQL, логически язык програмрования, и даже HTML и множестро где программист не забымывается как будет делать а заказывает что хочет получит и получает. Приэтом не следует путать эти парадигмы с одноименными стилями программрования.
Рисунок 1 Сравнение императивного и декларативного программирования
По своей сути все ПО предназначено для манипуляций данными с целью достижения определенного результата. Результат определяет способ структурирования данных, а структура данных определяет необходимый код.Но не наоборот. Тоесть нет смысла пложить бесконечное количество строк кода, беспонечное количество классов. Чем больше классов тем сложненее понимание всей архитектуры приложение , уменшение его надежности, усложнение тестированности, появление большео количества баов и значительное увеличесние времени на разработу и времени выполнения таких программ т к для их выполнения требуется большего количества ресурсов.
Рисунок 2 Классификация парадигм программирования
Этот момент очень важен, так что я повторюсь: цель -> архитектура данных -> код. Здесь порядок менять ни в коем случае нельзя! При проектировании программы нужно всегда начинать с выяснения цели, которой нужно достичь, а затем хотя бы приблизительно представить архитектуру данных: структуры и инфраструктуру данных, необходимые для ее эффективного достижения. И только после этого нужно писать код для работы с такой архитектурой. Если со временем цель меняется, то нужно сначала изменить архитектуру данных, а потом код.
По моему опыту, самая серьезная проблема ООП заключается в том, что оно мотивирует игнорировать архитектуру модели данных и применять бестолковый паттерн сохранения всего в объекты, обещающие некие расплывчатые преимущества. Если это подходит для класса, то это отправляется в класс. У меня есть Customer? Он отправляется в class Customer. У меня есть контекст рендеринга? Он отправляется class RenderingContext.
Вместо построения хорошей архитектуры данных внимание разработчика смещено в сторону изобретения «хороших» классов, взаимосвязей между ними, таксономий, иерархий наследования и так далее. Это не просто бесполезное занятие. В глубине своей оно очень вредно.
Таблица 1 Сравненине процедурного, ооп и функционального программирования.
Основа Для сравнения | POP | OOP | Функциональное программирование |
---|---|---|---|
основной | Процедура / структура ориентирована. | Объектно-ориентированный. | Функторы и монады |
Подход | Низходящий. | Вверх дном. | денотационной семантике выражения и использование редукции графа |
основа | Основное внимание уделяется «как выполнить задачу», т. е. задача разбивается на подзадачи на функции, процедуры . условные операторы могут использоваться как операторы if-else и оператор switch | Объекты, методы, классы. Основное внимание уделяется «безопасности данных». Следовательно, только объектам разрешен доступ к объектам класса., использование циклов для итерируемых данных,объект является основной единицей манипуляции. условные операторы могут использоваться как операторы if-else и оператор switch |
переменная, Функции высокого порядка, референциальная прозрачность ,f(a) == f(b) если a == b., чистые функции, рекурсия для итерируемых данных, функция является первичной единицей манипуляции. не поддерживает условные операторы. |
разделение | Большая программа делится на блоки, называемые функциями. | Вся программа делится на объекты. | вместо объектов, объединяющих данные с поведением, все разнесено раздельно на сами данные и на их обработчики. Каждый обработчик представляет из себя функцию, принимающую исходные данные и возвращающую результат. |
выполнение | операторы должны выполняться в определенном порядке. | операторы должны выполняться в определенном порядке. | операторы могут выполняться в любом порядке. |
Режим доступа к объекту | Спецификатор доступа не наблюдается. | Спецификаторы доступа: «открытый», «закрытый», «защищенный». | ,нет процедур |
Перегрузки / Полиморфизм | Ни перегружает функции, ни операторы. | Он перегружает функции, конструкторы и операторы. инверсия исходного кода и рантайм-зависимостей. | |
абстрагирование | в основном поддерживает абстракцию только над данными | поддерживает абстракцию над данными и абстракцию над поведением | |
наследование | нет наследования. | Наследование достигается в трех публичных и охраняемых режимах. | |
Сокрытие данных и безопасность | Нет правильного способа скрыть данные, поэтому данные небезопасны | Данные скрыты в трех режимах: публичном, частном и защищенном. следовательно безопасность данных увеличивается. однако методы объектов могут иметь побочные эффекты | функции не имеют побочных эффектов |
Обмен данными | Глобальные данные распределяются между функциями в программе. | Данные распределяются между объектами через функции-члены. модель программирования с сохранением состояния. состояние существует. | нет оператора присвоения, функции используют неизменные данные, модель программирования без сохранения состояния, состояние не существует
данные → функция1 → данные → функция2 → данные → функция3 → результат, |
Функции / классы друзей | Нет понятия функции друга. | Классы или функции могут стать друзьями другого класса с ключевым словом «друг». Примечание: ключевое слово "друг" используется только в C ++ |
Нет понятия функции друга. |
Виртуальные классы / функции | Нет концепции виртуальных классов. | Понятие виртуальной функции появляется при наследовании. | Нет концепции виртуальных классов. |
Скорость выполения, и ресурсоемкость | очень высокая | скорость выполения очень низкая, затрачивавание больших ресурсов пямыти и каналов связи, не подходит для обработки больших данных | высокую производительность при обработке больших данных |
Скорость разработки | очень низкая | высокая | низкая |
нативная поддержка паралелльного программмирования | нет | есть | |
назначение, применении и спользование | используется для выполнения нескольких операций, имеющих общее поведение и различные варианты. | используется для выполнения множества различных операций, для которых данные фиксированы. | |
пример | C, VB, Фортран, Паскаль, Ассемблер | C ++, JAVA, VB.NET, C # .NET. | F#,XSLT и XQuer,Haskell,Erlang ,Лисп , R |
Таблицу 1 конечно желательно расширить, добавив логическое программирование, SQL, и программирование на основе нейросетей, программрование на основе кубитов.
Несмотря на отдельные критические замечания в адрес ООП, в настоящее время именно эта парадигма используется в подавляющем большинстве промышленных проектов. Однако нельзя считать, что ООП является наилучшей из методик программирования во всех случаях.
Критические высказывания в адрес ООП:
Гради Буч указывает на следующие причины, приводящие к снижению производительности программ из-за использования объектно-ориентированных средств:
Динамическое связывание методов
Обеспечение полиморфного поведения объектов приводит к необходимости связывать методы, вызываемые программой (то есть определять, какой конкретно метод будет вызываться) не на этапе компиляции, а в процессе исполнения программы, на что тратится дополнительное время. При этом реально динамическое связывание требуется не более чем для 20 % вызовов, но некоторые ООП-языки используют его постоянно.
Значительная глубина абстракции
ООП-разработка часто приводит к созданию «многослойных» приложений, где выполнение объектом требуемого действия сводится к множеству обращений к объектам более низкого уровня. В таком приложении происходит очень много вызовов методов и возвратов из методов, что, естественно, сказывается на производительности.
Наследование «размывает» код
Код, относящийся к «конечным» классам иерархии наследования, которые обычно и используются программой непосредственно, находится не только в самих этих классах, но и в их классах-предках. Относящиеся к одному классу методы фактически описываются в разных классах. Это приводит к двум неприятным моментам:
Инкапсуляция снижает скорость доступа к данным
Запрет на прямой доступ к полям класса извне приводит к необходимости создания и использования методов доступа. И написание, и компиляция, и исполнение методов доступа сопряжены с дополнительными расходами.
Динамическое создание и уничтожение объектов
Динамически создаваемые объекты, как правило, размещаются в куче, что менее эффективно, чем размещение их на стеке и, тем более, статическое выделение памяти под них на этапе компиляции.
Если попытаться классифицировать критические высказывания в адрес ООП, можно выделить несколько аспектов критики данного подхода к программированию.
Критика рекламы ООП
Критикуется явно высказываемое или подразумеваемое в работах некоторых пропагандистов ООП, а также в рекламных материалах «объектно-ориентированных» средств разработки представление об объектном программировании как о некоем всемогущем подходе, который магическим образом устраняет сложность программирования. Как замечали многие, в том числе упомянутые выше Брукс и Дейкстра, «серебряной пули не существует» — независимо от того, какой парадигмы программирования придерживается разработчик, создание нетривиальной сложной программной системы всегда сопряжено со значительными затратами интеллектуальных ресурсов и времени. Из наиболее квалифицированных специалистов в области ООП никто, как правило, не отрицает справедливость критики этого типа.
Оспаривание эффективности разработки методами ООП
Критики оспаривают тезис о том, что разработка объектно-ориентированных программ требует меньше ресурсов или приводит к созданию более качественного ПО. Проводится сравнение затрат на разработку разными методами, на основании которого делается вывод об отсутствии у ООП преимуществ в данном направлении. Учитывая крайнюю сложность объективного сравнения различных разработок, подобные сопоставления, как минимум, спорны. С другой стороны, получается, что ровно так же спорны и утверждения об эффективности ООП.
Производительность объектно-ориентированных программ
Указывается на то, что целый ряд «врожденных особенностей» ООП-технологии делает построенные на ее основе программы технически менее эффективными, по сравнению с аналогичными необъектными программами. Не отрицая действительно имеющихся дополнительных накладных расходов на организацию работы ООП-программ (см. раздел «Производительность» выше), однако значение снижения производительности часто преувеличивается критиками. В современных условиях, когда технические возможности компьютеров чрезвычайно велики и постоянно растут, для большинства прикладных программ техническая эффективность оказывается менее существенна, чем функциональность, скорость разработки и сопровождаемость. Лишь для некоторого, очень ограниченного класса программ (ПО встроенных систем, драйверы устройств, низкоуровневая часть системного ПО, научное ПО) производительность остается критическим фактором.
Критика отдельных технологических решений в ООП-языках и библиотеках
Эта критика многочисленна, но затрагивает она не ООП как таковое, а приемлемость и применимость в конкретных случаях тех или иных реализаций ее механизмов. Одним из излюбленных объектов критики является язык C++, входящий в число наиболее распространенных промышленных ООП-языков.
Документирование классов — ресурсоемкая задача.
Резко увеличивается время на анализ и проектирование систем
Увеличение времени выполнения.
Размер кода увеличивается
Неэффективно с точки зрения памяти (мертвый код - тот, который не используется)
Сложность распределения работ на начальном этапе и при изменении архитектуры и функционала
Проблемы параллелизма Беспорядочное совместное использование изменяемого состояния в ООП делает распараллеливание такого кода практически невозможным. Для решения этой проблемы были изобретены сложные механизмы: блокировка потоков, мьютекс и многие другие. У таких сложных подходов есть свои недостатки — взаимоблокировки, отсутствие возможности компоновки, плюс отладка многопоточного кода очень сложна и отнимает много времени. Речь даже не идет об увеличении сложности, вызванном использованием таких механизмов параллелизма.
продолжение следует...
Часть 1 Недостатки ООП, DDD (Domain-driven design) и паттернов. Альтернатива ООП
Часть 2 Какие же есть решения проблем ООП? - Недостатки ООП, DDD
Часть 3 Имитация Сложности - Недостатки ООП, DDD (Domain-driven design) и паттернов.
Часть 4 Архитектурные шаблоны - Недостатки ООП, DDD (Domain-driven design) и паттернов.
Исследование, описанное в статье про недостатки ооп, подчеркивает ее значимость в современном мире. Надеюсь, что теперь ты понял что такое недостатки ооп, альтернатива ооп, ddd, архитектура программного обеспечения и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Объектно-ориентированное программирование ООП
Да если Рисунок 3 повернуть на 80 градусов против часовой стрелки то реально)) внизу грешные люди, пользователи, а вверху божества и ангелы, сверхвозможностями
Комментарии
Оставить комментарий
Объектно-ориентированное программирование ООП
Термины: Объектно-ориентированное программирование ООП