Лекция
Это продолжение увлекательной статьи про недостатки ооп.
...
отвлекаться, запомним лишь факт их существования.
Словари определяют, что само слово «сложный» является антонимом к слову «простой» и имеет несколько устоявшихся значений:
Если пристально вглядеться, в нашем мире и правда много сложного. Как нам думается. Навскидку, выписал слова, которые крутились в голове – ГОСТ, финансы, LESS, физика, Docker, ООП, Шаблоны проектирования, Опционы, АЭС и т.д. (см. КДПВ).
Хотя зачастую мы сами явно не упрощаем. Именно в IT-индустрии многие могут знать не понаслышке про такие проекты, где собиралась огромная бригада аналитиков и менеджеров, приносились фреймворки и Blue-Green развертывание, event-driven микросервисы и реактивные микрофронтенды. И вот спустя полгода человек жонглирует 30 серверами пытаясь понять в каком месте оно не работает. А нужна была лишь система обработки заказов, с пиковой нагрузкой в 100 пользователей.
Несмотря на то, что в этом мире существуют явно сложные задачи, тем не менее есть особая категория решений, которые строятся сложнее чем они могли бы быть построены (например, пишется больше кода чем необходимо для решения проблемы).
На мой взгляд, для описания подобной ситуации подходит слово «имитация» имеющее древние корни:
Когда мы имитируем сложность, у нас ее еще нет, но мы решили попробовать ей подражать. Это промежуточная серая область, когда разрабатываемое решение уже нельзя считать простым, однако и сложность пока выглядит сомнительно либо неуместно. Позвольте объяснить точнее, рассмотрим на условном примере.
Простое ← Имитация Сложности ← Сложное
Вам передают приложение, разработанное кем то иным, допустим REST API. Вы открываете и видите N проектов: контракты, ядро, данные, веб, фасады и т.д. Богато выглядит, думаете вы, наверняка оно решает нечто важное.
Открываете первый проект. Там 2 директории. 2 интерфейса на фасады. Некий интерфейс видимо указывающий на возможность валидации сущности. Хотя сущностей всего 2 и вроде и логично, что их можно валидировать.
Открываете фасады, думаете может там хитрость закопана. Там обнаружится всего два фасада, по одной реализации, без переключения с одной базы данных на другую или тому подобного. Закрадываются сомнения, а все ли так богато на самом деле.
Постепенно вы добираетесь до проекта Web, думается там вся соль! Ан нет, там только один контроллер и стандартная конфигурация.
Пример несколько гиперболизирован, однако ситуация многим может быть знакома.
Вопрос: На ваш взгляд, обоснована ли здесь такая организация кода, архитектуры, проектов?
Универсальный ответ — «зависит», ведь это зависит от контекста, от поставленной задачи и чего хотели достичь. Возможно это все будет еще расширяться, возможно нет, но если вдруг будет, приложение готово к расширению. Разумеется, я выступаю за продуманную организацию кода, а с другой стороны, вроде все это упаковывается в 2 проекта и несколько файлов, на первое время.
Рассмотрим другой пример.
Вы создаете новое приложение, допустим, REST API. Решив начать все с контроллера, вы описали контроллер, описали сущности контракта.
И ощущаете, вроде маловато. Надо еще ведь модульные тесты написать — создаете аксессор (и/или: репозиторий, UnitOfWork, DB-контекст, ...).
Потом идете на кухню попить чайку, открываете книгу про шаблоны проектирования, посещаете конференцию где вам рассказывают еще 3 истории успеха внедрения DDD и CQRS, т.е. вы где-то что-то зачем-то узнаете. Не успеваете оглянуться, вжух – кембрийский взрыв. В приложении появляются останки всех известных слов для выражения зависимостей:
Контракты, фасады, прокси, процессоры и т.д. и т.п. Я знаком с приложениями где больше слов, а делают они пока очень мало чего.
Справедливости ради, спустя 2 года эти приложения научились делать значительно больше и превратились в серьезные системы. Вот только некоторые зависимости так никогда и не были использованы, а некоторые раздробились на множество новых.
Вопрос: Насколько оно обосновано?
Опять-таки, возможно, все здесь и как надо, возможно усложнили код предполагая будущие задачи. Все зависит от контекста и наших целей. В теории правильно выстроенная архитектура и не должна позволять сделать неправильно. Однако, надеюсь я сумел донести саму идею существования определенной грани, когда реализуемая сложность еще не нужна, где начинается имитация сложности — будущей или вымышленной.
Мне доводилось самому делать такие приложения как показал на предыдущих слайдах – сразу все по полочкам, с горой терминов. Потом вернулся через 3 года и выкинул много лишнего, что так и не пригодилось.
Серая область имитации сложности довольно велика и относительна. Но чтобы ее лучше понять надо сначала осознать простое и сравнить сложное с простым.
Простое ← Имитация Сложности ← Сложное
Если существует сложность (и она измеряема), то с другой стороны должно быть нечто противопоставляемое, т.е. простое. Довольно давно сформулирован принцип KISS, про него немало всего написано и рассказано. Предлагаю рассмотреть какие преимущества нам дает простое решение.
Во-первых, простое решение быстрее реализовать. Уточню, реализовать изначально, тему дальнейшей поддержки/развития мы лишь отчасти затронем чуть ниже.
Безусловно, выбор решения во многом зависит от решаемой проблемы и поставленной задачи.
Сани, машина, ракета — все из этого позволяет добраться из пункта А в пункт Б.
Сани не сгодятся для полета в космос, зато их сделать быстрее чем космический корабль.
Если мы понимаем, что нам надо лишь съехать с горки, то быть может и куска линолеума хватит, а в этом случае даже сани будут являться имитацией сложности. Мы захотели на более вычурных санках съехать, хотя линолеум прекрасно справился бы, а могли сэкономить деньги и время.
Другой пример это когда вам необходимо доплыть до пункта Б.
Летом, чтобы доплыть до островка неподалеку, зачастую хватает ваших собственных рук и ног, в крайнем случае подручных средств. Смастерить плот и весло сложнее, чем проплыть немного самостоятельно, зато с плотом легче преодолеть большую дистанцию. Структура плота явно проще парусной яхты. Иногда вы арендуете уже готовую яхту с командой и задача поддержки сложности при этом перекладывается на другого.
Во-вторых, простое решение обеспечивает более надежную работу. Это заявление может выглядеть более спорным, а потому позвольте объяснить подробнее. Обратим наше внимание на названые ранее метрики сложности. Значение любой из них так или иначе прямо пропорционально числу «подвижных» частей нашего решения. Если мы входим в зону имитации сложности, мы начинаем добавлять код, вряд ли убавлять.
Вопрос: Какова вероятность ошибки или опечатки в строке кода? 1% или 0.1% или 0.01%?
Отчасти понадеемся на компилятор, он сможет обнаружить самые очевидные ошибки. Допустим мы уверены, что вероятность ошибки в строке кода крайне мала, пусть 0.01%. Перемножив вероятности ошибки на большом приложении с 10 000 строк кода, получаем 100%, что там есть ошибка. Что-то здесь не так...
Причем, исправление одной ошибки уменьшит вероятность следующей лишь незначительно, ведь эти события являются практически независимыми. Допустим мы пишем код идеально. Уменьшим вероятность еще на 2 знака, получим вероятность ошибки 1% на 10 000 строк кода. А потом вспоминаем, что у нас минимум 100 взаимосвязей или разных зависимостей между классами...
Продолжать можно бесконечно, хоть и к точности подсчета можно придраться, суть останется прежней: «Больше последовательных звеньев — ниже надежность». Сложность проверки превосходит количество строк кода в миллионы раз. Поэтому, чем меньше кода в вашем решении, тем выше вероятность надежной работы. Обычно.
В-третьих, простое решение понятнее для поддержки. Снова обратим наше внимание на метрики сложности, многие из которых означают – чем сложнее, тем больше у вас будет методов/классов/абстракций. Всевозможные шаблоны придуманы чтобы сокрыть сложность за некой абстракцией. Даже если они звучат лаконично, в реализации это может означать десятки классов, т.е. сложность зачастую привносит новые абстракции.
Абстракции это великолепный инструмент доступный человеческому разуму. Абстракции упрощают восприятие при моделировании, позволяют сокрыть сложность и абстрагироваться от деталей. Здесь мы спрятали за фасадом, здесь укрыли в репозиторий, и кажется сложности у нас совсем нет.
Если мы начинаем вводить абстракции заранее (а это почти всегда так), то что мы делаем? Имитируем будущую сложность. Проходит время и вы оказываетесь в роли знаменитой Даши. Где-то в глубине приложения что-то упало и вы начинаете копать.
Начинаем смотреть на наши зависимости приправленные любимым контейнером для внедрения.
Что-то там делается, вызывается менеджер с разными параметрами.
Идем дальше. Менеджер вроде тоже вполне прозрачный, зависимости какие-то, но параметры перекомпоновывает, поэтому надо разобраться как именно. Разобрались, идем дальше.
Открываем фасад, там еще порция зависимостей. Перегруппировка параметров и вызов дальше аксессора.
Открываем аксессор, нет зависимостей – ура! Подождите ка...
Видимо человек, кто писал аксессор на этом уровне, уже просто устал разбираться. Взял любимый логгер, указал хардкодом строку подключения для начала разработки, да так и оставил. Теоретически, архитектура не должна позволять делать такое. Только кто запретит человеку выстрелить себе в ногу? Возможно на код-ревью потом отловим. Возможно и не отловим, изменится строка подключения и все рухнет.
Этот пример о том, что вот я стал уставать от обилия абстракций. Здесь десяток абстракций запомни, здесь десяток, и вроде недолго разбираться, но время тратится. Грустно, хочется задачу решать, а не заучивать плоды чьей то фантазии.
Итого, простота ведет к Скорости (уменьшению затрачиваемого времени), к Надежности, к Поддерживаемости. Казалось бы,
«Обалдеть, дайте две!» ©
Замечательно, давайте делать все максимально просто, чего я вообще тут про имитацию распинаюсь. Почему мы не делаем все Просто? Разумеется, указанные параметры здесь встают в позу знаменитой тройки: лебедь, рак и щука.
( автор: Анна , 7 лет)
К сожалению, реально полноценно совместить лишь 2 аспекта, а 3-й обязательно будет страдать. Примерно как CAP теорема, или Тройственная ограниченность проекта, только про другое (очень уж людям нравится треугольники). Нам придется делать выбор, а выбор обусловлен целью и задачами, как мы помним. Решаемая задача каждый раз особая, где для одной допустимо простое решение, для другой придется усложнять. В одном случае топорное решение обеспечит страдания при поддержке, а в другом наоборот позволит быстрее переписать при необходимости.
Нередко встречаю аргументацию, мол бывает «сложное» решение реализовать даже «проще», зато с «простым» вы потом получите «сложные» проблемы. Однако, здесь легко можно попасть в лингвистическую и семантическую ловушку. Решение которое видится нам «простым», на самом деле может оказаться невероятно сложным с т.з. отдельных метрик. Лишь отчасти можно утверждать, что такое «сложное» решение «проще» подстраивать, т.е. обходиться компоновкой существующих деталей.
Попробуем подумать, зачем мы имитируем?
Причины могут быть разные, я не берусь сейчас разделять на «хорошие» или «плохие», но важно честно и рационально их оценивать.
Мне знакомы ситуации, когда люди привносили сложность т.к. им было стыдно показать простое решение. Они выходили на кухню, там все рассказывали про сложные шаблоны и рождалась мысль: «Как же я свои 2 класса покажу, это же все не по книгам».
Часто можно услышать и другую универсальную причину — сделаем гибче, еще гибче, на будущее. Мы многое можем спрятать под общими словами, не желая признать собственное непонимание решаемой задачи.
Не призываю совсем избегать сложности, ведь она бывает оправдана, да и зачастую она оправдана. Все-таки мы проблемы Бизнеса решаем, а не лямбдами балуемся.
Не призываю создавать только примитивные решения, ведь действительно с ними потом можно получить множество проблем при необходимости внести изменение. Если строить лишь телеги, то в космос не полететь. Хотя если строить лишь космические корабли, то и саночек не останется.
Многое в этом мире автоматизировано и успешно функционирует с использованием относительно простых решений. Признаю проблематичность подтверждения пруфами данного утверждения, оно основано скорее на личном общении. Можно вспомнить доклад Дилана Битти «Ctrl-Alt-Del: учимся любить легаси-код», где Excel упоминается как самая популярная в истории платформа для разработки коммерческих продуктов, а рядом бродит призрак Visual Basic. Знаю небольшие магазины, где долгие годы люди успешно работают с примитивнейшим полу-консольным интерфейсом кассовых аппаратов.
Призываю быть честными по отношению к себе, к коллегам и решаемой задаче. Давайте стараться всегда начинать с упрощения самой постановки проблемы еще до начала проектирования решения. Возможно, достаточно больших красных букв на странице, вместо механизма отката распределенных транзакций.
«Все следует упрощать до тех пор, пока это возможно, но не более того» © Альберт Эйнштейн
Упростив постановку проблемы и предлагаемое решение, вы получите пространство для маневра.
Если вы осознаете необходимость восхитительно гибкого механизма — прекрасно, вы эксперт, дерзайте.
Если вы хотите именно здесь опробовать новый подход и он не принесет страданий — замечательно, пробуйте.
Если же причин усложнять нет, а вас смущают лишь субъективные нерабочие факторы, разве это повод обеспечить трудности будущему себе?
Простое <—> Имитация Сложности <—> Сложное
Давайте чаще задумываться о простом, помня о преимуществах как сложных, так и простых решений. На мой взгляд, именно благодаря этому мы сможем свободно варьировать сложность в зависимости от реальных потребностей. Потом вам и другие скажут спасибо, и вы сами себе.
Еще я не люблю то, как всем нравится не любить чужие языки. Мы любим разделять мир на лагери: фигурные скобочки против квадратных против круглых.
Вот некоторые вещи, которые говорились о наших любимых ООЯП:
“Си позволяет легко выстрелить себе в ногу; с C++ это сделать сложнее, но, когда вы это делаете, вы отстреливаете себе ногу целиком.”
Это сказал Бьерн Страуструп, так что все хорошо.
“Я придумал термин ‘объектно-ориентированный’, и вот что я вам скажу: я не имел в виду C++.” — Алан Кей.
Мне очень жаль, что давным давно я ввел термин «объекты», потому что они заставляют многих людей сосредоточиться на менее важной идее. Основная же идея — обмен сообщениями. Алан Кей,
Java — самая неприятная вещь, случившаяся с компьютерами со времен MS-DOS.
Алан Кей, изобретатель объектно-ориентированного программирования
Алан Кей, изобретатель ООП
Алан Кей ввел термин «объектно-ориентированное программирование» в 1960-х годах. Он имел опыт работы в области биологии и пытался заставить компьютерные программы общаться так же, как живые клетки. Основная идея состояла в том, чтобы независимые программы (ячейки) общались, отправляя друг другу сообщения. Состояние независимых программ никогда бы не открылось внешней среде (инкапсуляция). Вот оно. ООП никогда не предназначался для наследования, полиморфизма, ключевого слова new и множества шаблонов проектирования.
“В C++ всего 2 вещи получились не так: начальный замысел и реализация.” — Бертран Мейер
“Внутри С++ сидит более компактный и понятный язык, отчаянно пытающийся выбраться наружу.” — Бьерн Страуструп
“C++ — это история, повторяющаяся как трагедия. Java — это история, повторяющаяся как фарс.” — Скотт МакКей
“Java, лучший аргумент за SmallTalk после C++.” — Фрэнк Винклер
Благодаря объектно-ориентированным языкам программирования, компьютерное программное обеспечение становится более многословным, менее читаемым, менее наглядным и более сложным для модификации и обслуживания.
Ричард Мэнсфилд
Наиболее важным аспектом разработки ПО является снижение сложности кода. Ни одна из фич не имеет значения, если кодовую базу становится невозможно поддерживать. В этом случае даже стопроцентное тестовое покрытие ничего не стоит.
Что делает кодовую базу сложной? Есть много вещей, на которые следует обратить внимание. На мой взгляд, главными причинами являются: общее изменяемое состояние, ошибочные абстракции и низкое отношение сигнал/шум (бойлерплейт). Все они распространены в ООП.
“Если бы у Java был настоящий сборщик мусора, большинство программ удаляли бы себя во время исполнения.” — Роберт Сьюэл
C++ — ужасный [объектно-ориентированный] язык… Ограничение вашего проекта до C означает, что люди не напортачат ни с какой идиотской «объектной моделью».
Линус Торвальдс, создатель Linux
Линус Торвальдс широко известен своей открытой критикой C++ и ООП. Одна вещь, в которой он был на 100 % прав — это необходимость ограничения программистов в выборе. На самом деле, чем меньше у программистов выбора, тем более устойчивым становится их код. В приведенной выше цитате Торвальдс настоятельно рекомендует иметь хороший фреймворк, на котором будет основан ваш код.
Многим не нравятся ограничения скорости на дорогах, но они необходимы, чтобы не дать людям разбиться насмерть. Точно так же хорошая среда программирования должна обеспечивать механизмы, которые мешают делать глупости. Хорошая среда помогает писать надежный код. Прежде всего, это должно помочь уменьшить сложность, предоставляя следующие вещи:
ООП предоставляет разработчикам слишком много инструментов и вариантов, не налагая правильных ограничений. Несмотря на обещания ООП рассмотреть модульность и улучшить возможность повторного использования, оно не выполняет свои обещания (подробнее об этом позже). ООП-код поощряет использование разделяемого изменяемого состояния, которое может быть небезопасно от раза к разу. ООП обычно требует большого количества бойлерплейта (низкого отношения сигнал/шум).
Я думаю, что большие объектно-ориентированные программы борются со сложностью, возрастающей по мере построения большого графа изменяемых объектов. Понимаете, это как пытаться понять и держать в голове, что произойдет при вызове метода и какими будут побочные эффекты.
Рич Хики, создатель Clojure
Состояние само по себе довольно безобидно. Но изменчивое состояние — большая угроза стабильности. Особенно, если его распространять. Что именно является изменчивым состоянием? Любое состояние, которое может измениться: переменные или поля в ООП.
Рассмотрим пример из реального мира. У вас есть чистый кусок бумаги, вы пишете на нем заметку. В результате вы получаете тот же кусок в другом состоянии (текст). Вы фактически изменили его состояние. Это вполне нормально в реальном мире, поскольку никто не заботится об этом куске бумаги. Если только это не оригинальная картина «Мона Лиза».
И, возможно, наиболее всеобъемлющий приговор:
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
Классы сводят меня с ума. Это может показаться странным, так что позвольте объяснить.
Кажется, что классы — это удобно. Наш мозг превосходно классифицирует информацию, которую мы получаем из окружающего мира. И было бы вполне естественно классифицировать все в объектно-ориентированных программах.
Однако в реальном мире есть только объекты. Классы существуют только в нашем сознании. Можете ли вы привести хоть один пример из реального мира, что класс — это реальная, физическая сущность? Нет, не думаю.
И вот в чем проблема. Вы когда-нибудь задумывались, почему программу на объектно-ориентированном языке понять настолько сложнее, чем на процедурном?
В процедурных программах процедуры вызывают другие процедуры. Процедурный код показывает… процедуры, вызывающие другие процедуры. Все хорошо и просто, так ведь?
В объектно-ориентированных программах объекты посылают сообщения другим объектам. Объектно-ориентированный код показывает… классы, наследующие другие классы. Ой. Кажется, что в ООП между исходным кодом и исполняемой программой нет никакой связи. Наши инструменты плохо помогают нам: IDE ведь показывают классы, а не объекты.
Я думаю, поэтому SmallTalk’еры так любят программировать в дебаггере: последний дает им почуствовать контроль над исполняемыми объектами и позволяет программировать их напрямую.
Вот, что я бы хотел сказать разработчикам инструментов: пожалуйста, дайте нам IDE, которая будет показывать объекты вместо классов!
Методы или свойства, которые обеспечивают доступ к определенным полям, не лучше, чем непосредственное изменение значения поля. Не имеет значения, изменяете ли вы состояние объекта с помощью необычного свойства или метода, результат один и тот же — измененное состояние.
Честно говоря, методы я тоже терпеть не могу.
В реальном мире нет методов. Имеет ли лист бумаги, на котором вы пишете, метод «записи»? Нет. Вы просто берете пустой лист бумаги, берете ручку и пишете текст. Вы, как человек, тоже не имеете метода «записи» — вы принимаете решение написать какой-то текст на основе внешних событий или ваших внутренних мыслей.
Как мы все понимаем, методы в хороших объектно-ориентированных программах должны быть короткими и изящными. Множество маленьких методов удобнее для разработки, понимания, повторного использования и так далее. Так в чем же проблема?
Примем во внимание то, что на чтение объектно-ориентированного кода мы тратим больше времени, чем на его написание. Это и называется производительность: вместо того, чтобы часами писать большое количество кода, чтобы добавить новый функционал, мы пишем всего лишь несколько строчек, но при этом часами пытаемся понять, какие именно строчки нужно написать!
Одна из причин, почему мы тратим столько времени, в том, что нам приходится листать код туда-сюда… через множество маленьких методов.
Это также известно как синдром Затерянных в космосе и об этом говорится со времен создания ООП. Цитируя Адель Голдберг, “В SmallTalk все происходит где-то еще”.
Я уверен, что винить в этом стоит сегодняшние кодоориентированные IDE — учитывая, что объектно-ориентированный код не дает представлений об исполняемом приложении, IDE встает на нашем пути вместо то, чтобы помогать. Другая причина, по которой SmallTalk’еры так любят программировать в дебаггере — он помогает им хорошо видеть, какие объекты с какими взаимодействуют. Поэтому, я думаю, сегодня популярна разработка через тестирование (test-driven development, TDD), позволяющая увидеть взаимодействие объектов во время разработки.
И дело не в самом ООП — мы просто еще не поняли (после более чем 40 лет), как надо разрабатывать программы для него. Мы должны задаться вопросом: почему исходный код остается преобладающим отображением в IDE?
Я хочу IDE, которая позволит мне переключаться между кодом и исполняемым приложением. (Для получения представления об этой идее, загляните на сайт платформы для веб-разработки Seaside, позволяющей переключаться прямо с исполняемого приложения на редактируемый исходный код)
Ладно, признаю: я нетерпелив и ненавижу повторять слова дважды. Типы же заставляют меня это делать.
Кто-то сейчас наверняка подумал: “Но как же ты можешь писать на бестиповом языке. Ты никогда не будешь уверен, что твой код правилен.”
Конечно, “бестиповых” языков не существует — существуют статически и динамически типизированные. Статически типизированные мешают писать код в некоторых случаях. В принципе, ничего плохого в этом нет.
Проблема с самими типами, какими мы их знаем. Во-первых, они дают приводят к чувству ложной безопасности. То, что ваша Java программа компилируется, не означает, что в ней нет ошибок (и даже ошибок с типами).
Во-вторых и в-главных, типизация предполагает, что мир постоянен, а программы в нем состоят из неизменных частей, а это не так. Из-за этого некоторые полезные типы программ (особенно рефлексивные) становится сложнее писать.
И наконец, типизация плохо ладит с тем фактом, что существуют разные понятия типов. Не бывает одной всемогущей системы. Вспомните те страдания, которые мы испытывали с обобщениями в Java. Сейчас разрабатывается много полезных систем типов, но расширить Java, чтобы уместить их все, мы не можем. Гилад Браха предложил сделать типизацию не только необязательной, чтобы запускать программы даже в том случае, если типизация некорректна, но и подключаемой, такой, чтобы мы смогли подключать разные системы типов в разных частях наших программ. Мы должны подумать над этим предложением, а заодно и над тем, как адаптировать языки программирования и среды разработки к разнообразным системам типов.
“Перемены неизбежны — в отличие от мелочи из торгового автомата.” — Роберт Галагер
Мы все не любим меняться, правда? А если так, то почему же жалуемся, если вещи не становятся лучше? Мы знаем, что полезные программы должны меняться, или со временем они ухудшаются.
(Между прочим, знаете, в чем разница между железом и софтом? Железо ухудшается, если вы не поддерживаете его в рабочем состоянии.)
Учитывая, что реальные программы должны меняться, справедливо полагать, что языки и IDE должны поддерживать это. Предлагаю вам, однако, назвать хоть один механизм в языках программирования, который поддерживает изменчивость. Те механизмы, которые работают с изменчивостью, скорее, ограничивают и контролируют ее.
Наш мир непостоянен, но мы хорошо себя в нем чувствуем. Контекст — вот то, что позволяет нам справляться с переменами. Мы подстраиваем наше поведение, наши ожидания под контекст, в котором находимся, но наши программы почему-то ломаются, если контекст меняется.
Я хочу увидеть эту идею в объектно-ориентированных языках и IDE. Как исходный код, так и исполняемое приложение должны иметь возможность подстраиваться под изменяющийся контекст. Уверен, что многие шаблоны проектирования и идеи (такие как посетитель и внедрение зависимости) — всего лишь костыли, которые исчезнут после реализации механизма контекстов в ООЯП.
Некоторые утверждают, что изменяемое состояние — решение разработчиков в ООП, а не данность. Но это не так. Это не выбор разработчиков, а практически единственный вариант. Да, неизменяемые объекты можно передавать в методы Java/C#. Но это делается редко, поскольку большинство разработчиков по умолчанию используют изменение данных. Даже если разработчики пытаются использовать неизменяемость в своих программах ООП, языки не предоставляют встроенных механизмов для неизменяемости и для эффективной работы с неизменяемыми данными (то есть постоянными структурами данных).
Можно сделать так, что объекты будут общаться только путем передачи неизменяемых сообщений и никогда не будут передавать никакие ссылки (что на самом деле редкость). Такие программы будут более надежными, чем основные в ООП. Но объекты все еще должны изменить свое собственное состояние после получения сообщения. Сообщение является побочным эффектом, и его единственная цель — вызвать изменения. Сообщения были бы бесполезны, если бы они не могли изменить состояние других объектов.
Невозможно использовать ООП, не вызывая изменения состояния
Паттерны. Не могу с ними, не могу без них.
Каждый шаблон проектирования делает ваш проект запутаннее.
ООП предоставляет набор рекомендаций, которые теоретически должны позволить разработчикам постепенно наращивать все большие и большие системы: принцип SOLID, внедрение зависимостей, шаблоны проектирования и т. д. К сожалению, шаблоны проектирования — это не что
продолжение следует...
Часть 1 Недостатки ООП, DDD (Domain-driven design) и паттернов. Альтернатива ООП
Часть 2 Какие же есть решения проблем ООП? - Недостатки ООП, DDD
Часть 3 Имитация Сложности - Недостатки ООП, DDD (Domain-driven design) и паттернов.
Часть 4 Архитектурные шаблоны - Недостатки ООП, DDD (Domain-driven design) и паттернов.
Исследование, описанное в статье про недостатки ооп, подчеркивает ее значимость в современном мире. Надеюсь, что теперь ты понял что такое недостатки ооп, альтернатива ооп, ddd, архитектура программного обеспечения и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Объектно-ориентированное программирование ООП
Да если Рисунок 3 повернуть на 80 градусов против часовой стрелки то реально)) внизу грешные люди, пользователи, а вверху божества и ангелы, сверхвозможностями
Комментарии
Оставить комментарий
Объектно-ориентированное программирование ООП
Термины: Объектно-ориентированное программирование ООП