Лекция
Это продолжение увлекательной статьи про недостатки ооп.
...
закрылись после применения ООП
При проектировании архитектуры данных в явном виде результатом обычно является минимальный необходимый набор структур данных, обслуживающих цель нашего ПО. Если мыслить в категориях абстрактных классов и объектов, то грандиозность и сложность абстракций сверху ничем не ограничивается. Просто взгляните на FizzBuzz Enterprise Edition — такую простую задачу можно реализовать в столь большом количестве строк кода лишь потому, что в ООП всегда есть место для новых абстракций.
Защитники ООП скажут, что проверка абстракций — вопрос уровня навыка разработчика. Возможно. Но на практике ООП-программы всегда разрастаются и никогда не уменьшаются, потому что ООП стимулирует к этому.
Так как ООП требует разбрасывания информации по множеству мелких инкапсулированных объектов, количество ссылок на эти объекты тоже растет взрывными темпами. ООП требует передавать повсюду длинные списки аргументов или непосредственно хранить ссылки на связанные объекты для быстрого доступа к ним.
У вашего class Customer есть ссылка на class Order, и наоборот. class OrderManager содержит ссылки на все Order, а потому косвенно и на Customer. Все стремится ссылаться на все остальное, потому что постепенно в коде появляется все больше мест, ссылающихся на связанный объект.
Вам нужен был банан, но вы получили гориллу, держащую банан, и целые джунгли.
ООП-проекты обычно выглядят не как качественно спроектированные хранилища данных, а как огромные спагетти-графы объектов, указывающих друг на друга, и методы, получающие огромные списки аргументов. Когда вы начинаете проектировать объекты Context просто для того, чтобы урезать количество передаваемых туда-сюда аргументов, то понимаете, что пишете настоящий ООП-код уровня Enterprise.
Erlang – это ООП в чистом виде. В отличие от большинства мейнстримных языков, он сосредотачивается вокруг главной идеи ООП – обмена сообщениями. В Erlang объекты взаимодействуют путем передачи неизменяемых сообщений между собой.
А есть ли доказательства превосходства неизменяемых сообщений над вызовами методов?
Конечно! Erlang – это, возможно, самый надежный язык в мире. Он поддерживает основную часть мировой инфраструктуры телекома (следовательно, и интернета). Некоторые системы, написанные на Erlang надежный на 99.9999999%.
Подавляющее большинство существенного кода не работает всего с одним объектом, а на самом деле реализует задачи поперечных срезов. Пример: когда class Player ударяет при помощи метода hits() class Monster, где на самом деле нужно изменять данные? Величина hp объекта Monster должна уменьшиться на attackPower объекта Player; величина xp объекта Player должна увеличиться на уровень Monster в случае убийства Monster. Должно ли это происходить в Player.hits(Monster m) или в Monster.isHitBy(Player p)? Что если здесь нужно учитывать и class Weapon? Мы передаем аргумент в isHitBy или у Player есть геттер currentWeapon()?
Этот упрощенный пример со всего тремя взаимодействующими классами уже становится типичным кошмаром ООП. Простое преобразование данных превращается в кучу неуклюжих взаимопереплетенных методов, вызывающих друг друга, и причина этого только в догме ООП — инкапсуляции. Если добавить в эту смесь немного наследования, то мы получим хороший пример того, как выглядит стереотипное ПО уровня Enterprise.
ООП требует упорядочивать данные негибким образом: разделять их на множество логических объектов, что определяет архитектуру данных — граф объектов с относящимся к ним поведением (методами). Однако часто полезно бывает иметь разные возможности логического выражения манипуляций с данными.
Если данные программы, например, хранятся в табличном, ориентированном на обработку данных виде, то можно создать два или более модулей, каждый из которых работает с той же структурой данных, но различным образом. Если данные разбиты на объекты с методами, то это больше невозможно.
Это еще и является основной причиной объектно-реляционного разрыва. Хоть реляционная структура данных и не всегда бывает наилучшей, она обычно достаточно гибка, чтобы с ней можно было работать различными способами, пользуясь разными парадигмами. Однако жесткость организации данных в ООП вызывает несовместимость с любой другой архитектурой данных.
Самый важный аспект разработки – это постоянное понижение уровня сложности. Красивые фичи теряют смысл в коде, который невозможно поддерживать. Даже 100% покрытие тестами ничего не стоит, если код становится слишком сложным.
Что усложняет код? В основном общее изменяемое состояние, ошибочные абстракции, низкое отношение сигнал/шум (часто вызываемое шаблонным кодом). Об этом говорит сайт https://intellect.icu . Все это распространено в ООП.
«Я думаю, что большие объектно-ориентированные программы борются со сложностью, возрастающей по мере построения большого графика изменяемых объектов. Ну, знаете, когда вы пытаетесь понять и держите в памяти то, что произойдет при вызове метода, и какие будут побочные эффекты.» – Ричард Хикки, создатель языка программирования Clojure.
Состояние само по себе безвредно. Но изменяемое состояние – это большой нарушитель. Особенно если оно общее. Что такое изменяемое состояние? Любое состояние, которое может измениться. То есть, переменные или поля в ООП.
ООП ухудшает проблему организации кода, разбрасывая состояния по программе. Затем разрозненное состояние беспорядочно делится между разными объектами.
Не все состояния – зло . Получается, состояния – зло? Нет, изменение состояния, наверное, нормально в случаях настоящей изоляции (не ООП-изоляции).
Вполне нормально иметь неизменяемые объекты передачи данных. Ключевое слово здесь – «неизменяемые». Такие объекты используются для передачи данных между функциями.
Так или иначе, такие объекты сделают методы и свойства ООП абсолютно избыточными. Какой смысл в методах и свойствах объекта, если они не могут быть изменены?
Беспорядочный доступ к изменяемому состоянию делает параллельность в таком коде невозможной. Для решения этой проблемы был предложен сложный механизм. Блокировка потоков, Мьютекс и другие сложные механизмы. Конечно, они имеют недостатки – взаимные блокировки, нехватка композиционности, а отладка многопоточного кода очень сложна и отнимает много времени.
Сочетание разброса данных по множеству мелких объектов, активное использование косвенности и указателей, отсутствие правильной архитектуры данных приводят к низкой скорости выполнения. Такого обоснования более чем достаточно.
Часто просто создали универсальную систему способную решить якобы любую задачу исключительно через DDD типа такой -
Рисунок 3 Один из шедевров полиграфии для библии по DDD
Люди, очнитесь! такую систему можно нарисоввать с любой методологией, практикой и концепцией в центре!!!
это всего лишь цветная картинка с буквами DDD в центре!
Вам это не напоминает заблуждения с красивыми речами и картинками с геоцентричной системой во времена средневековья?
Рисунок 4 Иллюстрация геоцентрической системы мира из атласа Андрея Целлария Harmonia Macrocosmica (1708 г)
ответив на этот вопрос вы залезаем в еще больеш болото в котором одни проблемы заменятся на другие. Рассмотрим их подробнее
Если прочиать книги Jimmy Nilsson. Applying Domain-Driven Design and Patterns: With Examples in C# and .NET.
то можно прийти к выводу что сочинял ее, довольно среднений программист. Все в основном такое, что и без этой книги должно быть понятно любуму суслику, если конечно, этот суслик задумается об этом. Ни одной значительной мысли, ни чего нового, ни одного оригинального, или хотя бы старого, но переосмысленного расуждения и умозаключения.
Фактически в книгах DDD сводится к разработке не на основе предметной области, а на основе модели предметной области. То есть, подменили предметную область моделью, а вернее – даже не моделью, а кубиками и стрелками, и поехали по старой схеме: рисуем свойства, методы, пишем код. А где предметная область? Да ну ее, просто модное словечко, надо же тиражи поднимать и колво вебиранов.
Что касается самой концепции DDD, то она фактически сводится к довольно банальному утверждению:
DDD - разрабатывать программы нужно на основе предметной области.
Здрассте, приехали!
Оказывается, до сих пор еще есть те (и оказывается их много!), кто разрабатывает программы, игры, системы без учета, или не на основе предметной области?
А на чем же тогда? На своих представлениях о том, как надо программировать? На основе базы данных, как говорится в книге? (автор ее долгое время оказывается так и делал!). Для нормального разработчика это – абсурд. Да и вобще, для любого специалиста звучит диковато.
Самое смешное, что эта банальная концепция всерьез и на достаточно длительное время стала «модной» в программистском мире. Это ли не признак застоя? Оказывается, и программистам можно впаривать всякую чушь, были бы деньги. Вспомним как придумал забатывал один человечек. Главное хорошо говрить и писать)
Как вы думаете за чьи услуги, книги и за 45 минут простой словесной болтавни вам придется заплатить от $50 до $250 (тем не менее в Америке этим увлекается каждый седьмой, в Европе — каждый пятый)? А?. Человека, придумавшего такой заработок, зовут его Зигмунд Фрейд, так вот, все писаки пытающие найти прешения проблем ООП, в виде святого грааля,
так и порадийные методологии
Похоже, самым мощным инструментом в программном обеспечении стала реклама, ненужные книги, семинары и вебинары по том чего нет.
Но главное даже не это. Главное то, что критики, нормальной, здравой, практически не видно.
Не стоит относиться серьезно к любой методологии — к сожалению саморекламы там зачастую больше чем содержания.
не забывайте два главных принципа анализа - одно из правил диалектики -
все имеет достоинства и недостатки, тоесть не может быть идеальным, и использоваться единолично.
и второе
еще 10 веке Пьер Абеляр говрил что
Исходным пунктом любого исследования является сомнение, и дело ученого(разумного человека) состоит в том, чтобы, следуя путем разума, перейти от сомнения к истине. Это возможно только при последовательном и правильном применении диалектики (логики). Диалектический разум — это разум вопрошающий, находящийся в постоянном поиске, подвергающий сомнению даже утверждения Священного Писания, но с целью более глубокого его понимания. Диалектический разум, возвышающийся над обычным человеческим разумом, стремится приблизиться к Божественному Логосу
третье
Помните, что математические формулы - это аналог кода, а они не патентуются. т к есть множественные изоморфы ибо нет смысла раздувать их, а значит и объем программного кода должно быть минимальным для решения всей логики. Этим можно ускорить сроки разработки и повысить надежность и качество программного обеспечения и дать возможноть больше зарабовать вашему заказчку ил ивам еслм вы делаете свой проект
Венемся к нашим driven development и книге Нильсона, Ее нужно рассматривать примерно так же как "Patterns of Enterprise Application" Фаулера (естественно, классом пониже, текстом пожиже, бредом погуще). Если читали Фаулера, то часть паттернов не то чтобы устарела, но вызывает ощущение вторичности — "это же уже есть в [подставить любимую платформу], зачем размазывать?". Есть офигеннейшие шансы что вторична именно фича платформы, но вы-то ее изучили раньше
Если читать Эванса то можно заметить в нем отличногно пиарщика и популяризатор, но со своими странностями.
Как вы и писали, идея доменной модели у Эванса слегка вторична — еще в семьсят лохматом в ANSI/SPARC от DBTG был conceptual level — та самая "общая модель всего". Правда, речь тогда шла об архитектуре СУБД, а не о священной корове бизнес-логики DDD — было еще не модно. Эххх, какая тема пропадает — проследить долю исследований, где упоминается business logic.))
В той же книжке Эванса про DDD он шизофренично смешивает 2 модели:
— Domain как модель предметной области заказчика
— и Domain как ОО-модель предметной области программы
В чем разница? В первом варианте у нас получается очень интересная штука — относительно формальное описание правил по которым строится бизнес-логика. Во-втором — БЛ уже у нас на борту вместе с шлюхами, блэкджеком и агилистами — Эванс пару раз проезжается по ним в духе "при некоторых усилиях DDD таки можно использовать в agile-driven проектах".
Он явно не беседовал с фанатами от "код-как-модель".
Первый вариант для меня симпатичней именно своей простотой — у нас есть общая штука, нагруженная именно настолько чтобы быть поддерживаемой и полезной. И что самое главное — эта штука абсолютно не зависит от желаний разработчика/заказчика. При достаточной адекватности, разумеется.
DDD выстрелила (да и то не сразу — в каком у нас году вышла DDD: Tackling complexity?) как идея что ажиль еще жив и может порождать новые идеи — потому как "следуйте заповедям и обрящете если не проект, то уж душевное спокойствие" слегка поднадоело. В этом смысле — да, DDD есть целиком и полностью коньюктура и ничего ценного в себе не несет.
Вообще, выражения, заканчивающиеся на «driven development» — это уже такой программистский фольклор.
Многие кто посещает такие вебинары по DDD или покупает книги не имеет образование в области computer science, но умеет красиво говрить и доказывать.
Они например не знат что есть множетсвто моделей для БД, напрмиер можно начать проектирование с концептуальной формы БД, совместно с CRUD matrix + USe case и очень активным общением с заказчком. В нашем мире все начинается именно с сущностей, которые прекрасно хранятся в реляционных или не редяционных таблицах, и в четких правилах (простых и суперпозиционных) и для этого нет смысла создавать методы типа ->getAllCategoriesByHousesAndCityesInCoutry() ...
Вы представляете насколько жестким код ваш становится , на сколько много лишнего и не гибкого и не уверсального в вашей системе, престаляете что будет если заказчик захочет измемнить в логике делать тоже самое без стран?
Но вернемся к ООП, что же не так с ним? В таком духе я и подготовил скромный список несколких вещей, которые я терпеть не могу в ООП.
Что же есть парадигма объектно-ориентированного программирования? Есть ли на это прямой ответ? Я слышал столько разных версий, что и сам теперь не знаю.
Если мы посмотрим на идеи Smalltalk’а, мы столкнемся с мантрой: “Все есть объект”. Кроме переменных. И пакетов. И примитивов. Числа и классы тоже не совсем объекты, и так далее. Очевидно, “все есть объект” не может быть основой парадигмы.
Что для ООП является фундаментальным? Питер Вегнер однажды предположил, что основой объектно-ориентированного программирования являются объекты, классы и наследование. Однако, каждый язык программирования поддерживает их по-разному, или даже не поддерживает по умолчанию некоторые из них. Ясно, что это тоже не парадигма ООП.
Другие заверяют, что ООП — это Инкапсуляция, Абстракция и Сокрытие данных. Правда, разные источники скажут вам, что это всего лишь разные слова для описания одинаковой идеи. А другие скажут, что это три фундаментально разные концепции.
С середины 80-ых об ООП гуляет несколько мифов. Один из них, Миф о повторном использовании, гласит, что ООП делает разработку продуктивней, потому позволяет наследовать и расширять текущий код вместо того, чтобы всякий раз писать его заново. Другой, Миф о проектировании, который подразумевает, что анализ, проектирование и реализация плавно следуют друг из друга, потому что все они — суть объекты. Конечно же, ни один из этих мифов не может быть парадигмой ООП.
ООП пытается моделировать все как иерархию объектов. Но это не так. Объекты в реальном мире взаимодействуют друг с другом с помощью сообщений, но в основном они независимы друг от друга.ООП-наследование не отражает наследование реального мира. Родительский объект не может изменить поведение дочерних объектов во время выполнения. Даже если вы наследуете свою ДНК от родителей, они не могут вносить изменения в вашу ДНК по своему усмотрению. Вы не наследуете поведение от своих родителей. Вы развиваете свое поведение. И вы не можете переопределить поведение своих родителей.
Часто упоминается, что инкапсуляция является одним из величайших преимуществ ООП. Предполагается защитить внутреннее состояние объекта от внешнего доступа. Но есть небольшая проблема. Это не работает.Инкапсуляция — это троянский конь ООП. Он продвигает идею общего изменяемого состояния, делая его, казалось бы, безопасным. Инкапсуляция позволяет небезопасному коду проникать в кодовую базу (и даже поощряет это), заставляя ее гнить изнутри.Часто твердят, что глобальное состояние является корнем всех бед и его следует избегать любой ценой. Инкапсуляция, по сути, является глобальным состоянием. Чтобы код был более эффективным, объекты передаются не по значению, а по ссылке. Вот где «внедрение зависимости» падает в грязь лицом.Позвольте объяснить. Всякий раз, когда создается объект, ссылки на его зависимости передаются конструктору. Эти зависимости также имеют свое внутреннее состояние. Вновь созданный объект хранит ссылки на эти зависимости в своем внутреннем состоянии, а затем изменяет их любым удобным для него способом. Он также передает эти ссылки на все остальное, что может в конечном счете использовать. Это создает сложный граф разнородных общих объектов, которые изменяют состояние друг друга. Это, в свою очередь, вызывает огромные проблемы. Становится почти невозможно увидеть, что вызвало изменение состояния программы. Дни могут быть потрачены впустую в попытках отладить такие изменения. И вам повезет, если не придется иметь дело с параллелизмом (подробнее об этом позже).
Я думаю, что невозможность повторного использования затрагивает объектно-ориентированные, а не функциональные языки. Поскольку проблема с ООП-языками заключается в том, что у них есть вся эта неявная среда, которую они носят с собой. Вы хотели банан, а получили гориллу с бананом и целые джунгли в придачу.
Джо Армстронг, создатель Erlang
Наследование не имеет ничего общего с реальным миром. Оно является худшим способом достижения повторного использования кода. Банда четырех недвусмысленно рекомендовала отдавать предпочтение композиции перед наследованием, а некоторые современные языки программирования вообще его избегают.
Есть несколько проблем с наследованием:
Алмазная проблема в наследованиии классов
Рано или поздно следующая проблема порождает уродливую и, в зависимости от языка, неразрешимую головоломку.
Рисунок 5 Алмазно-брилиантовая проблема ООП в наследовании классов
Большинство ОО-языков не поддерживают это, хотя это кажется логичным. Что такого сложного в поддержке этого на ОО-языках?
Хорошо, представьте следующий псевдокод:
Обратите внимание, что и класс Scanner, и класс Printer реализуют функцию, называемую start .
Так какую функцию запуска наследует класс Copier ? Сканер один? Принтер один? Это не может быть и то и другое.
Решение алмазной(брилиантово) проблемы. Решение простое. Не делай этого. Да все верно. Большинство ОО языков не позволяют вам сделать это.
Но, но ... что если мне нужно смоделировать это? Я хочу свое повторное использование!
Тогда вы должны содержать и делегировать(Contain and Delegate) .
Обратите внимание, что класс Copier теперь содержит экземпляр Printer и Scanner . Он делегирует функцию запуска реализации класса Printer . Он также может быть легко передан в сканер .
Эта проблема - еще одна трещина в колонне Наследования.
Полиморфизм великолепен, он позволяет изменять поведение программы во время выполнения. Это очень базовая концепция в компьютерном программировании. Я не очень уверен, почему в ООП ему уделяют так много внимания. Он выполняет свою работу, но в очередной раз приводит к умственному жонглированию. Это делает кодовую базу значительно более сложной. Анализ конкретного метода, который вызывается, становится очень трудным.
Функциональное программирование позволяет добиться того же полиморфизма гораздо более элегантным способом — просто передав функцию, определяющую желаемое поведение во время выполнения. Что может быть проще этого? Не нужно определять кучу перегруженных абстрактных виртуальных методов в нескольких файлах (и интерфейсе).
Как обсуждалось ранее, инкапсуляция — троянский конь ООП. На самом деле это глобальное изменяемое состояние, благодаря которому небезопасный код выглядит безопасным. Небезопасная практика написания кода — это основа, на которую программисты ООП полагаются в своей повседневной работе.
Шизофреническая инкапсуляция объектов. Давайте взглянем на определение инкапсуляции:
Инкапсуляция — концепция ООП, связывающая данные и функции для манипулирования этими данными, позволяющая защитить их от внешнего вмешательства и неверного использования. Инкапсуляция данных привела к важной для ООП концепции сокрытия данных.
Намерение благое, но на практике инкапсуляция при дробности объекта или класса часто приводит к тому, что код пытается отделить все от всего остального (от самого себя). Это создает огромный объем бойлерплейта: геттеры, сеттеры, многочисленные конструкторы, странные методы, и все они пытаются защитить нас от ошибок, возникновение которых слишком маловероятно в таких скромных масштабах. Можно использовать такую метафору: я нацепляю на левый карман висячий замок, чтобы правая рука не могла ничего из него взять.
Не поймите меня неверно — наложение ограничений, особенно в случае ADT, обычно является хорошей идеей. Но в ООП со всеми этими перекрестными ссылками объектов инкапсуляция часто не достигает ничего полезного, а учитывать ограничения, разбросанные по множеству классов, довольно сложно.
По моему мнению, классы и объекты слишком дробные, и с точки зрения изоляции, API и т.д. лучше работать в пределах «модулей»/«компонентов»/«библиотек». И по моему опыту, именно в кодовых базах ООП (Java/Scala) модули/библиотеки не используются. Разработчики сосредоточены на том, чтобы соорудить ограждения вокруг каждого класса, не особо задумываясь над тем, какие группы классов в совокупности формируют отдельную, многократно используемую, целостную логическую единицу.
Нам говорили, что инкапсуляция – одно из главных преимуществ ООП. Она должна защищать внутреннее состояние объекта от внешнего доступа. С этим тоже есть небольшая проблема. Она не работает.
Инкапсуляция – это троянский конь ООП. Он продает идею общего изменяемого состояния под предлогом безопасности. Инкапсуляция позволяет (и даже поощряет) проникновение небезопасного кода в наши исходники.
Абстракция в ООП пытается решить сложность, скрывая ненужные детали от программиста. Теоретически, это должно позволить разработчику анализировать кодовую базу, не думая о скрытой сложности.
Причудливое слово для простой концепции. В процедурных/функциональных языках вы можете просто «спрятать» детали реализации в соседнем файле. Нет необходимости называть этот основной акт «абстракцией».
Давайте взглянем на другие парадигмы, позволяющие решать программистские задачи определенным образом. Процедурное программирование часто описывается как программы = данные + алгоритмы. Логическое программирование гласит: программы = факты + правила. Функциональное программирование, по всей видимости, программы = функции + функции. Что наводит на мысль, что ООП означает программы = объекты + сообщения. Так ли это? Я думаю, что тут теряется главное. А главное в том, что ООП – это не парадигма, как например процедурное, логическое или функциональное программирование. Вместо этого ООП говорит: “для каждой отдельной задачи вы должны разработать свою собственную парадигму”. Другими словами, парадигма объектно-ориентированного проектирования такова: “Программирование — это моделирование”.
Нам говорили, что глобальное состояние – корень всех зол. Нужно избегать его, чего бы это ни стоило. Нам никогда не говорили, что инкапсуляция, по факту, вершина глобального состояния.
Для эффективности кода объекты передают не свои значения, а их ссылки. Вот где «внедрение зависимости» терпит неудачу.
Когда мы создаем объект в ООП, мы передаем ссылку на его зависимости в конструктор. Эти зависимости также имеют собственные внутренние состояния. Вновь созданный объект с радостью хранит ссылки на эти зависимости в своем внутреннем состоянии, а затем с радостью изменяет их любым удобным для него способом. А также он передает эти ссылки всему остальному, что он может в итоге использовать.
Это создает сложный график беспорядочных общедоступных объектов, которые меняют состояния друг друга. Что, в свою очередь, приводит к огромным проблемам, так как отследить причину изменения состояния программы становится практически невозможно. Можно потратить много дней на отладку подобных изменений состояния. И вам повезло, если вам не нужно разбираться еще и с параллелизмом.
Методы и свойства, которые предоставляют доступ к определенным полям ничем не лучше прямого изменения полей. Неважно меняете ли вы состояние объекта с помощью красивого свойства метода – результат один: измененное состояние.
Программисты могут часами размышлять о правильных шаблонах и красивых абстракциях. Как сделать еще гибче, еще круче, еще сложнее. Как усложнить. Обычно мы двигаемся от простого к сложному.
Простое → Сложное
На доклад меня подвигло именно то, что мы мало говорим о простом. По крайней мере в моем окружении мало разговоров об этом. Существуют статьи восхваляющие простые решения, но таковых довольно мало и чаще мы говорим о сложном. Давайте сегодня пройдемся от сложного к простому, через таинственную имитацию сложности. Предлагаю всем вместе подумать, почему мы так мало говорим про простые решения и много концентрируемся на сложных.
Простое ← Имитация Сложности ← Сложное
Если говорить про сложное и сложность, то вроде и много всего написано, а все равно я ощущаю нехватку материалов. Размышляя про код, модули или архитектуру, мы интуитивно понимаем что такое маленькое и большое. Можем примерно отличить нечто простое (как кирпич) и интуитивно понимаем когда творится хаос (с лапшой). Так или иначе, все эти термины связаны с понятием сложности.
Вопрос: Попробуйте подумать, повспоминать и ответить на следующие вопросы:
Обозначений сложности много, она многогранна, перечислим лишь наиболее известные:
К сожалению, зачастую люди находят информацию лишь про SLOC, где обнаруживают критику, что метрика устарела с развитием языков, и на этом изучение теории сложности программного обеспечения завершается. Различные метрики сложности программного обеспечения мы постараемся разобрать в следующей статье (надеюсь). Сейчас же не будем
продолжение следует...
Часть 1 Недостатки ООП, DDD (Domain-driven design) и паттернов. Альтернатива ООП
Часть 2 Какие же есть решения проблем ООП? - Недостатки ООП, DDD
Часть 3 Имитация Сложности - Недостатки ООП, DDD (Domain-driven design) и паттернов.
Часть 4 Архитектурные шаблоны - Недостатки ООП, DDD (Domain-driven design) и паттернов.
Исследование, описанное в статье про недостатки ооп, подчеркивает ее значимость в современном мире. Надеюсь, что теперь ты понял что такое недостатки ооп, альтернатива ооп, ddd, архитектура программного обеспечения и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Объектно-ориентированное программирование ООП
Ответы на вопросы для самопроверки пишите в комментариях, мы проверим, или же задавайте свой вопрос по данной теме.
Да если Рисунок 3 повернуть на 80 градусов против часовой стрелки то реально)) внизу грешные люди, пользователи, а вверху божества и ангелы, сверхвозможностями
Комментарии
Оставить комментарий
Объектно-ориентированное программирование ООП
Термины: Объектно-ориентированное программирование ООП