Интересно про монолит, очень! Запишите в формате типа Монолит VS Микросервисы Да и вообще, расскажите про оба подробно, а потом это сравнение или наоборот.
Да госпаде) если ОЧЕНЬ интересно, то у Немчинского есть на этом канале несколько видео, в каждом одна и та же лекция прямо про это. Он в одном видео так и сказал: "мои зрители не знают, что я снимал раньше, поэтому имеет смысл повторять те же темы каждый год". И натурально повторяет) Прям можно прогресс видеть, что изменилось, а что излагает как прошлый раз.
Только на днях наткнулась в вакансии на требование "Понимание базовых принципов разработки SOLID, KISS, DRY;" и тут же решила пересмотреть существующие видосы на эту тему😄 Немчинскому респект за полезную и нужную информацию!!! 👍
Очень интересное объяснение. Особенно интересно по примеры когда DRY не применим. О том где это не применимо еще ни от кого кроме уважаемого автора не слышал. Спасибо.
Принцип великолепный, но есть и исключения. Например, создаем мы мобильное приложение, в нем есть разные экраны. Между некоторыми экранами мы видим схожие черты, и мы выделяем единый модуль, который настраивается клиентским кодом на разных экранах по-разному. А потом внезапно заказчик мутитрует этот модуль на всех экранах в совершенно разные стороны. Приходится или люто расширять интерфейс и возможности по кастомизации (что снижает эффективность обобщения, ведь мы хотели сделать этот модуль автономным и забыть о нем), или докидывать вспомогательные классы и перебалансировать модуль (рушим принцип OpenClosed и переписываем половину модуля заново). А можно просто не бежать впереди паровоза и не обобщать раньше времени то, в чем ты не уверен. Иногда оставить в разных местах почти одинаковый код - неплохое решение.
Я бы выделили еще пару мест-исключений: 1. Написание юнит-тестов. Простой тест без наследований, импортов и вызовов функций легко читается, легко и быстро можно понять, что там сломалось 2. Сериализаторы. Их проще каждый раз создавать заново, чем наследовать, изменяя список полей. При большом дереве наследования легко запутаться
Немного удивила позиция Сергея насчет автогенерации кода. Впрочем, я думаю, его мнение справедливо в первую очередь для бэкенда. А вот на Андроиде как минимум тот же Dagger (DI-фреймворк) формирует зависимости модулей именно статическим путем - генерацией кода. И да, он вполне читабельный. Раньше, как мне известно, для этих целей использовалась рефлексия, но это было чревато снижением производительности и отсутствием возможности отладки до запуска и компиляции, т.е. если для какого-то модуля недостает какого-то другого, то в случае с автогенерацией это можно выяснить при компиляции. Для меня это огромный плюс. Я и так хорошо поломал голову над DI, когда его осваивал, если бы ошибки всплывали только в рантайме - понадобилось бы больше времени на набивание шишек и выяснения того, как нужно сделать так, чтобы заработало. А еще ORM (Room) формирует огромный сгенерированный говнокод для взаимодействия с SQLite, а разработчик лишь пишет Dao-интерфейс с SQL-командами в аннотации, а все остальное генерирует annotation processor. Насколько я знаю, на бэкенде (в Spring вроде бы) используется именно рефлексия для DI. Но там и масштабы другие и производительности хватает для всяких рант-тайм штук.
да, видео про монолитные системы было бы кстати; можно ещё подискутировать почему монолитное ядро линукс вытеснило модулярные и гибридные ядра, популярные в то время
Дискутировать в общем то и неочем, проект gnu так и не смог создать нормально работающее микроядро, а работать было надо, вот и взяли монолит Линуса. Microsoft сделали микроядро, но были просадки по скорости, поэтому впихнули в ядро графическую подсистему, получилось гибридное ядро.
Что-то мне сегодня ютуб вас подкидывает ) Вам весьма повезло, если считаете, что программисты знают что надо этот DRY использовать. Для баз данных еще есть какое-то понимание, почему там нельзя дублировать данные. А вот, как только начинают класс писать, С ХОДУ, вот прямо как только подумал, что классу что-то надо, сразу скопировал данные в поля класса. Не из источника брать, а только дублировать )) Мало того, и код дублируют, причем настойчиво, думая что это хорошо, доказывая что это хорошо, и иногда думая, что это я старый и не шарю в мегакрутом подходе для сервисов и микросервисов )) Это вроде в сервисах не может быть общего кода. Т.е. настойчиво, в рамках одной системы, пишут компоненты, где вот тупо одно и то же несколько раз написано. А потому что сервис. А потому что в каком-то странном их воображении, так безопаснее, мол они независимые, у них только интерфейс. Зато, когда приходит требование изменять, надо во всех модулях менять. На счет генерации кода, я пользую, сам пишу генераторы или трансляторы. Но это когда никак иначе. Например, для какой-то своей ORM, надо классы для мапа в базу данных. Вообще, отношусь где-то так. Генерация лучше чем ничего, т.е. чем дублировать работу руками. То что там говнокод генерится, не страшно, главное что без ошибок. На то она и генерация, не для людей. Но, при этом, чаще всего, надо смотреть в сторону, а нет ли баги в архитектуре, раз нужна генерация. Потому что в первую очередь надо приводить саму архитектуру к такому виду, чтобы не нужно было дублировать что-либо, а генерация говорит о том, что автоматизировали рутину. Но наверное, ее вообще не должен код требовать.
Мне приходилось дублировать код в Angular. В нескольких компонентках код был схож на ~70%. Да, можно было схожий код запихнуть в отдельную компонетку и ее использовать во всех тех компонентках. Все это хорошо, но я понимал, что при первой же доработке любой их этих компоненток придется все переделывать. Там было логично оставить дублирующий код.
В одном из проектов был бизнес леер. На основе его паблик метов, генерировался прокси, который вклчючал в себя логирование, откат трансакций, выполнение на другом потоке и многое другое. Перегенерирование случалось когда изменялись сигнатуры публичных методов. Вот для чего это нужно. И работало все как часы. Вот вам еще пример автогенерации, который мне кажеться очень крут. При добавлении обектов, генерируются их билдеры, спомощью которых, можно легко создать нужный объект и написать тест.
Про генерацию кода - можно поспорить, а лучше послушать мнение от Сергея по поводу DSL(Domain Specific Language). Иногда проще разработать небольшой язык и описать систему на нем, а далее сгененрировать код на общем языке(Java, C# и тд) У JetBrains прям целая платформа есть MPS для этого Обычно DSL понятен не только программисту, но и аналитику, тестеру, клиенту. В идеале сами требования транслируются прямо в код на общем языке Ждем видео по DSL
Дублирование в легаси может появиться не с пустого места и решать какие-то проблемы. В частности при переходе/миграции между разными платформами часто делают поэтапный переход с поддержкой двух параллельно развивающихся систем. Авто-генерация тоже не грех. Особенно, если генерация API идёт через JSON-схему. Это позволяет отвязать API от реализации на конкретном языке и платформе. Ещё дублирование может быть вызвано оптимизациями запросов в БД, либо потребностью хранить в истории операций дополнительную информацию, не относящимися к самой операции (например, баланс счёта до и после операции, а не только сумму списания/зачисления), тоже самое и про дублирующиеся проверки на фронте и бэке.
Прекрасный принцип и другое название SSO (single source of truth) ему очень подходит. Недавно столкнулся, когда в двух местах в программе у меня генерился GUID и я не понимал, а почему на определённом этапе у меня в базе в Redis данные начали задваиваться и вот после долгого дебага я выяснил, что генерация нового ГУИДА происходила в двух местах. Очень важный принцип, с которым столкнулся при довольно сложных обстоятельствах.
Вот кстати на счёт изменение кода во всех местах - это не всегда так. Очень часто бывает так что изменение нужно только в одном месте (по разным причинам, но зачастую потому что это другая часть программы и мы не хотим ее трогать)
Ещё пример нарушения dry - когда один и тот же модуль написан на разных языках, например под процессор и под видеокарту. Не всегда удаётся эти две имплементации как-то обобщить
А если клиент и сервер пилят разные организации? Это довольно часто случается. У нас, к примеру, фронт пилят партнеры (у каждого свои команды и инструменты). А мы пилим серверную часть. Валидацию пишем так, будто клиент на своей стороне ничего не проверяет. Но надеемся, что какие-то данные они все же проверяют, прежде чем отправить запрос нам =)
Еще пример возможно нарушающий DRY, это CQRS + ES и построение представлений в отдельной бд, то есть данные в итоге имеют разную структуру но по факту повторяются.
Автогенерация частенько нужна в сетевых протоколах между разными языками, и должна производится на этапе сборки проекта, а кодеген не должен отдаваться под СКВ, это просто промежуточный артефакт сборки (ну, если мы рассматриваем систему нормальных людей). Иногда кодеген нужен и для всякого сетевого транспорта низкого уровня в рамках одного языка, когда нужны сложные взаимодействия и нужно быстродействие, поэтому никакого доступа к рефлекшну и подобных вещей допускать нельзя, а хочется всякие данные прямо таки упаковывать поБИТно в поток, при этом описывая свои данные по-человечески, удобными декораторами и т.п. Естественно, сгенеренный код НЕ меняется вручную НИКОГДА. Если нужно расширить его функционал, нужно расширять саму кодо-генерацию. Однако кейсы, когда это действительно нужно - есть.
Очень нравятся видео этого автора, но вот не соглашусь с тем, что если код повторяется, то его нужно обязательно натянуть на DRY. Очень частый случай, в моей практике, когда начинаешь писать код (проект или компонент еще молодой и не оброс деталями). Коды очень похожи, повторяются некоторые шаги, но есть и различия. Прежде чем начинать делить, дробить чтобы соблюсти DRY нужно проаналазировать причины для изменения (как раз SRP) если код будет меняться с разной скоростью, если он будет меняться по разным причинам и в будущем еще и планируется, что его будут поддерживать разные команды со своими ТЗ, то беспрекословное следование принципу DRY очень усложняет развитие. В какой то книге я даже читала что этот случай называется: случайное дублирование. И ни раз я сталкивалась с ситуацией когда на начальном этапе коды очень схожи, их выносят в переиспользуемый блок, а потом начинается прирастание всякими if else. И проблемами со слиянием.И еще неприятнее: если нарушается вариантность при поддержке разными командами. Может, конечно я лишь подтвердила мысль обозначенную в последнем разделе видео. Если так, то извиняюсь
Щодо генерації коду, я б не був таким категоричним. Ми на проєктах використовуємо typescript generator, який генерує з java DTO їх аналоги в typescript. Нічого поганого в тому нема, хоч і наш фронт-енд ПОВНІСТЮ залежить від згенерованих класів. Ніяких проблем з тим нема, навіть більше того, то нас береже від помилок з літерувками. Другий приклад. Ми мали проєкт, де була купа табличок, в яких була купа фільтрів. Але була вимога до нашого API, що практично кожен метод який повертав дані для таблички, мав піти продубльований, щоб він ще й повертав ті самі дані в CVS файлі. Ми написали модуль, який генерував контроллери, в яких були ті самі методи, але з суфіксом '.../csv'. Код там був так собі, але зате ми скоротили кодову базу на 30%.
Вы про DRY в ДБ говорите. Про денормализацию слышали? Дублирование данных допустимо, если есть причины. Более того, нарушение Драй допустимо и в коде. Эти принципы не высечены в фундаменте разработки. Есть случаи когда дублировать код вполне допустимо. Так как переиспользуемый функционал может расширяться и спустя время вырастать в монстра. Updated...
Andrew Reznik, мне, как новичку, это видео полезно. Лучше ведь начать обучение с тем подходом, который пригодится в 80% случаях. Сергей говорит о том, что есть исключения.
Сергей Спасибо за видео. Какой тип паттерна архитектуры программного обеспечения можно использовать для (DRY). Пожалуйста, пример с открытым исходным кодом
Real time играм, которые интерполируют на клиенте пока сервер не ответил, не обязательно нарушать принцип dry. Принцип dry про непереписывание кода дважды. Но один и тот же код два раза в двух местах исполнять вполне нормальо ничего не нарушая. Просто его нужно вынести в переиспользунмый модуль. Некоторые высокоуровневые сетевые фреймворки в некоторых игровых движках типа Unet в Unity вообще позволяют не думать сервер ты или клиент, ты просто пишешь что происходит в общем, а дальше все само разделяется (ок, это слегка упрощение конечно). Если бэк и фронт на совсем разных технологиях, то тут дублирование логики нужно или действительно переписывать или брать/изобретать некие декларативки с генераторами кода. Типа как какой нибудь ProtoBuf. Если они есть конечно.
Следуя принципу DRY нужно не уходить совсем в фанатизм. Переиспользоваться должна логика, а не просто код. Если код похож, но является частью выполнения различных задач - это не кандидат на попытку куда-то его вынести.
Стало интересно: а распределенные базы данных - это нарушение принципа dry? Ведь одни и те же данные лежат в разных местах, плюс еще изза ошибок обмена или репликации могут не сходиться.
Постоянно вижу дублирование кода, в некоторых CMS большие куски кода дублируются десятки раз. Это очень плохо, т.к. они с этим живут десятки лет. Да и у меня это иногда само собой получается. А бывают случаи, когда более правильно скопировать метод и переписать часть функционала, и при этом не выносить общий кусок в третий метод. При этом получится 2 метода с частично дублированнм кодом. Но дублированние данных - это скорее нонсенс.
Сергей, а как быть если генерирование кода используется для проектов на нескольких языках? Скажем есть firmware на CPP и GUI на JAVA- и там и там одинаковые сущности с одинаковым поведением, генерация позволяет синхронизировать изменения в описании сущности сразу в 2 языках.
В этой самой книге, которую вы упоминаете (The Pragmatic Programmer), есть глава о том, что надо использовать автогенерацию кода). Вроде в разделе The Basic Tools. Книга в целом хорошая, но местами устарела. А ваш видос - это лайк!
Пример с табличками плохой. Хранилища данных часто создаются не так, чтоб программистам было удобно, а чтоб запросы и BI приложения быстро работали. Если очень нужно, то архитектор данных вполне может разместить те-же данные в нескольких таблицах. Не говорю что это прямо хорошо с точки зрения программиста, скорее о том, что так часто бывает.
Услышал ваше мнение о кодогенерации, однако, небезизвестный Алан Кей сотоварищи продвигает STEPS, система с иерархической кодогенерацией. Каково ваше мнение об этой системе?
srp не задевает dry никак. srp это когда fun doStuff() { // generating stuff ... ... // processing stuff ... ... } никаких дупликаций нет, но один метод выполняет несколько шагов (и хорошо, когда они никак не пересекаются, а то они могут смешаться, могут одни переменные из прошлого шага уходить в следующий, и столько всего ещё может быть). хороший вариант будет таким fun doStuff() { val stuff = generateStuff() processStuff(stuff) } такой код становится понятным и читаемым без комментариев (которые к слову зачастую тоже ошибки, комментарии стоит делать только у методов, но не у строчек кода, если функция pure, то комментарий к функции должен всё объяснять) часто srp всякие геймдевы нарушают, которые не особо заботятся о кодстиле и сначала генерят локацию, а потом расставляют на ней каких-нибудь человечков, в лучшем случае, добавляя комментарии
Здравствуйте. Есть у меня такой вопрос. Нарушает ли (или имеет ли отношение к) принципы DRY такой кусок кода. this.variableA.variableAA = someValue this.variableA.variableAB = someValue2 this.variableA.variableAC = someValue3 this.variableA.variableAD = someValue4 Вопрос в том должна ли бить вынесена this.variableA в отдельную переменную во избежание дубликаций val myVariable = this.variableA myVariable..variableAA = someValue ...
если база хранится в одной базе "долгого хранения", а для быстрого поиска в виде дерева в другой БД, реалтайм. нарушение? если сделано осознанно из-за ограничения по времени выполнения запроса. запись в обе БД из одного скрипта.
одна и та же логика для валидации на фронте и на бэке, логика над данными в актуальной системе и в миграции (которая валидна на какой то момент времени только, а дальше ее могут менять). код, оптимизированный на что-то в одном месте и в других местах общего вида код. на самом деле кучу таких примеров можно найти и иногда копи-паста лучше чем упоротый dry в вакууме. нету универсального подхода) все эти подходы о которых идет речь это скорее то к чему следует стремиться, но оно никогда не работает на практике в его стерильном определении
Да, и я про то-же. Если есть система, которая генерирует классы/методы, время ограничено, бьюджет так-же, дальнейшее развитие и доработка очень маловероятны, то смысла не имеет рефакторить такой проект. Утверждение, что дублирование кода недопустимо - верно только для дорогих систем с длительной поддержкой и разработкой. Для одноразовых дешевых поделок (которых большиснтво в Вебе) это не верно.
@@Merk462 одноразовые дешевые поделки вообще писать смысла нет. Берется какой-нибудь Salesforce или Bitrix или вообще Wordpress и тупо натягивается на клиентский дизайн-макет. Или даже тупо покупается готовый шаблон. Для этого даже прогер не нужен.
Проблема в том, что в рамках одного языка программирования оно не работает даже для одного проекта , не говоря о наследовании между разными проектами. Как пример, возьмите какую-нибудь средненькую поделку с вебом, и внимательно посчитайте сколько одну и ту же конепцию переписываете на яве, жаббаскрипте, sql/хранимки/констрейнты, сериализации, формы/вьюхи, для мобилы, в документации,..
Потом добавьте пару заказчиков с перламутновыми пуговицами, миграните на соседний фреймворк или найдите ошибку в дизайне... Именно про это и была фраза про автогенерацию - без выхода на метауровень, на уровень абстракции моделей и дизайна ПО, DRY нереализуем
При программировании на видеокартах бывает быстрее именно скопировать код в память видеокарты и заново рассчитать, чем обращаться к коду в оперативную память через медленные шины. И если, например, в микроконтроллере мало памяти, то писать несколько функций, выполняющих похожие вычисления, пусть даже для разных задач - расточительство. Для низкоуровневых программистов и микроконтроллерщиков все эти советы не работают.
@@SergeyNemchinskiy Где? Прочтите "Повесть об одном байте". Вам понравится )))) Или например, CFX-расчёты, когда обрабатываются многомиллиардные массивы данных, и дополнительная строчка кода приводит к дополнительному месяцу вычислений, и все эти ваши ООП вылетают, как слепые котята. Советы для программистов офиснопланктонных программ, не более того.
А ведь у меня в универе реально были такие случаи, но только с файлами Microsoft Office (к примеру, на моём компе документ отображается правильно, а на компах в универе нет)
Спасибо за обзор, Сергей. Не согласен с принципом - нужно или не нужно дублировать данные - если это дает прирост производительности к их чтению-записи на больших объемах - дублировать (кусками) - это решение. Например, 1С основана на принципе дублирования данных. Когда в базе за месяц миллион документов создаются, то любое чтение-запись этого миллиона займет неделю.
про дублирование данных - да очень банально. Взял данные из одного источника - раздал их по API - вот тебе и дублирование =). Какой-то второй консьюмер оперся на копию данных, решил срастить их с третьими данными, и может оказаться что копия еще не в синке, и консьюмер не может срастить 1 с 2. По большому счету "пофиг", со временем все равно синканется, но как в той песне - "а что если нет?" =) Что если синк сломался по какой-то причине? =)
Вопрос, а что про модульность? Тоесть если в моем проекте есть сущность "Новости", и есть ... "Статьи", они очень похожи архитектурно, но предметно разные. Если я выведу всё в переиспользование то изменение Новостей изменит Статьи, но если не переиспользовать то местами будет 1в1 одинаковый код.
Но вы же будете в рантайме создавать два разных экземпляра объектов, поэтому они будут жить своей независимой жизнью. А вот класс, который будет создавать объекты и для статей и для новостей будет один.
@@sterlo-x8z я к тому веду, что абстрактно - это разные сущности, и если две (и более) сущности будут зависеть от реализации (так совпало что логика в них одинаковая) то мы нарушаем DIP, и если придет программист Петя и поправит "новость" думая что поступает правильно, цепляет ещё и "статьи" и ему от тестирования приходит ошибка с левого модуля. и т.о. модульность тоже нарушается (правим один модуль, не так работает другой)
Вы привели пример какого-то такого себе программиста и его проект с базой данных, - - - -> где информация дублируется, - - - - - - - -> но в коде надо вручную вписывать два раза. Может лучше просто написать подпрограмму, которая вставляет в два места? [face palm]
на самом деле макросы и шаблоны м с++ и есть автогенерация кода. зачем писать одинаковую имплементацию для разных типов данных, например матрица от дабл или флоат. так что да. шаблоны как раз для DRY
"Уай" Надеюсь ты английский прокачаешь до уровня С1, чтобы понимать эти тонкости произношения. Сергей получше тебя знает произношение английской буквы "Y" и применяет "проглатывание" звука. Про элизию почитай. Чтобы тебе было проще понять это, начни с изучения элизии постфиксов "ся" и "сь" в русском языке.
Дублирование кода не отменяет его понимания, если все четко осознается и применяется в своем софте не может быть ни каких проблем, ну зачем тратить время на написание функции еще раз ? Есть входные параметры и нужное на выходе, для чего писать самому тоже самое и тратить время ? Возможно для самоутверждения, с этим я соглашусь, но это будет влиять на время написания кода, реально смысла в этом ни какого нет. Прокладки используют те кто не умеет создать подобное на оригинале.
Главное соблюдая DRY не упускать из виду DRAE (Don't repeat anyone else). Ну и печалька, если прилетает проект на Go с монгой в качестве базы... У создателей этих поделок явно аллергия на DRY
А что там не так? Просто никогда не сталкивался с Go, тем более в связке с монгой. А так на монгу сейчас многие хотят переехать. Вернее многие хотят 2 базы - что-то SQL-based как основная и еще склад документов всяких на монге.
@@homo-ergaster с go основная проблема в почти полном отсутствии полиморфизма, есть только некое подобие на базе утиной типизации. В неопытных руках, а на go таких большинство, код превращается в лютую кашу, где одно и то же написано в десятке мест. Да и в опытных руках, этот ад заменяется кодогенерацией, что не на много лучше. Кстати, о руках, на go 2 типа разрабов - совсем неопытные юнцы, пришедшие в сферу как правило из-за денег (как итог быстро сливаются), либо нормальные спецы, но пришедшие с других ЯП, каждый со своим подходом и пришедшие сюда от какой-либо безысходности... Ну и еще про DRY в go, просто попробуйте посчитать количество if err != nil в любом проекте... Что касательно монги, все будет ок, если данные не сильно связаны, но я таких данных пока еще не видел (если они относятся к одному бизнесу конечно), добавим сюда полную бесструктурность базы - и вот, каждый городит кто во что горазд. Нормальных джойнов тоже нет (опять же в последних версиях добавили некое подобие outer join в агрегацию, но ситуацию не спасает). Ну и часто встречал, "мы хотим именно монгу, ибо она у нас уже есть, а ваш посгрес (или чтото более подходящие) мы админить не умеем"... В принципе, что монга, что go неплохо себя показывают при прототипировании, когда на них делаешь что-то с нуля, оно действительно выходит быстрее. Но проблема большинства менеджеров/продактов, что они не выбрасывают прототипы после +/- удачного экспиримента, не понимая, что берут время в кредит под огромный %... А поддерживать кашу в коде на go и в данных в монге тот еще ад...
Сергей, у вас отличные видео, и подача, и материал - на высоте, более того - вы в теме преподавания, а значит вы знаете цену самосовершенствованию, к тому же у вас учатся люди. Ваши ошибки, даже мелкие - осядут в головах тех, кто вас слушает, даже такая мелочь, как произношение DRY. Вы выкладываете видео на платформе, на которой есть носители практически любого языка. Написав “don’t repeat yourself” в поиске, можно получить однозначный ответ - как правильно произносить термин, принесенный из другого языка, если термин не авторский - вряд ли есть место авторскому произношению.
Согласен, не стоит повторять самого себя.
Согласен, не стоит повторять самого себя.
Согласен с предыдущим оратором, поэтому просто сошлюсь на его слова.
Интересно про монолит, очень!
Запишите в формате типа Монолит VS Микросервисы
Да и вообще, расскажите про оба подробно, а потом это сравнение или наоборот.
+
Да госпаде) если ОЧЕНЬ интересно, то у Немчинского есть на этом канале несколько видео, в каждом одна и та же лекция прямо про это. Он в одном видео так и сказал: "мои зрители не знают, что я снимал раньше, поэтому имеет смысл повторять те же темы каждый год". И натурально повторяет) Прям можно прогресс видеть, что изменилось, а что излагает как прошлый раз.
не так давно был стрим где этой теме было посвящено не мало времени
@Владислав Бахмацкий иди своей дорогой, сталкер)
"нижний плечевой пояс" - супер!
Только на днях наткнулась в вакансии на требование "Понимание базовых принципов разработки SOLID, KISS, DRY;" и тут же решила пересмотреть существующие видосы на эту тему😄 Немчинскому респект за полезную и нужную информацию!!! 👍
Предлагали целоваться насухую?
"Принцип диареи" - звучит просто отпад)))))
Очень интересное объяснение.
Особенно интересно по примеры когда DRY не применим.
О том где это не применимо еще ни от кого кроме уважаемого автора не слышал.
Спасибо.
Принцип великолепный, но есть и исключения.
Например, создаем мы мобильное приложение, в нем есть разные экраны. Между некоторыми экранами мы видим схожие черты, и мы выделяем единый модуль, который настраивается клиентским кодом на разных экранах по-разному. А потом внезапно заказчик мутитрует этот модуль на всех экранах в совершенно разные стороны.
Приходится или люто расширять интерфейс и возможности по кастомизации (что снижает эффективность обобщения, ведь мы хотели сделать этот модуль автономным и забыть о нем), или докидывать вспомогательные классы и перебалансировать модуль (рушим принцип OpenClosed и переписываем половину модуля заново).
А можно просто не бежать впереди паровоза и не обобщать раньше времени то, в чем ты не уверен. Иногда оставить в разных местах почти одинаковый код - неплохое решение.
Потом в каждую из копий кода вносить правки, так утомляет, лучше уж наколхозить вставок, чем это
Я бы выделили еще пару мест-исключений:
1. Написание юнит-тестов. Простой тест без наследований, импортов и вызовов функций легко читается, легко и быстро можно понять, что там сломалось
2. Сериализаторы. Их проще каждый раз создавать заново, чем наследовать, изменяя список полей. При большом дереве наследования легко запутаться
Интересно про монолит!)
Вообще спасибо за то, что Вы есть.
Дякую, Сергiй! Якраз шукав iнфу про це, чудове пояснення!
Ну как, чудодейственные пояснения помогли - код превратился в DRY?
Класс! Какой порядок в голове после Ваших видео!
Немного удивила позиция Сергея насчет автогенерации кода. Впрочем, я думаю, его мнение справедливо в первую очередь для бэкенда.
А вот на Андроиде как минимум тот же Dagger (DI-фреймворк) формирует зависимости модулей именно статическим путем - генерацией кода. И да, он вполне читабельный. Раньше, как мне известно, для этих целей использовалась рефлексия, но это было чревато снижением производительности и отсутствием возможности отладки до запуска и компиляции, т.е. если для какого-то модуля недостает какого-то другого, то в случае с автогенерацией это можно выяснить при компиляции. Для меня это огромный плюс. Я и так хорошо поломал голову над DI, когда его осваивал, если бы ошибки всплывали только в рантайме - понадобилось бы больше времени на набивание шишек и выяснения того, как нужно сделать так, чтобы заработало.
А еще ORM (Room) формирует огромный сгенерированный говнокод для взаимодействия с SQLite, а разработчик лишь пишет Dao-интерфейс с SQL-командами в аннотации, а все остальное генерирует annotation processor.
Насколько я знаю, на бэкенде (в Spring вроде бы) используется именно рефлексия для DI. Но там и масштабы другие и производительности хватает для всяких рант-тайм штук.
Про генерацию кода. Android Studio жестко на него завязан. Половина современных библиотек зависит от кода, генерируемого плагинами Gradle.
да, видео про монолитные системы было бы кстати; можно ещё подискутировать почему монолитное ядро линукс вытеснило модулярные и гибридные ядра, популярные в то время
Не заметил в видео информации и монолитных системах.
@@Pchelinskii_Sergei 11:05
Дискутировать в общем то и неочем, проект gnu так и не смог создать нормально работающее микроядро, а работать было надо, вот и взяли монолит Линуса. Microsoft сделали микроядро, но были просадки по скорости, поэтому впихнули в ядро графическую подсистему, получилось гибридное ядро.
Голосую за видео про преимущества монолитных систем!
Убедили! Никогда не буду повторять себя в коде, чтобы потом там не искать свои копипасты. Спасибо!!!
фон - огонь
Чашка на столе тоже
Спасибо. Стараюсь вникать в "правильные" правила кодинга ))) И просто интересно
Спасибо за видео 🙂
обожаю ваши учебные видео. продолжайте!
Что-то мне сегодня ютуб вас подкидывает )
Вам весьма повезло, если считаете, что программисты знают что надо этот DRY использовать. Для баз данных еще есть какое-то понимание, почему там нельзя дублировать данные. А вот, как только начинают класс писать, С ХОДУ, вот прямо как только подумал, что классу что-то надо, сразу скопировал данные в поля класса. Не из источника брать, а только дублировать )) Мало того, и код дублируют, причем настойчиво, думая что это хорошо, доказывая что это хорошо, и иногда думая, что это я старый и не шарю в мегакрутом подходе для сервисов и микросервисов )) Это вроде в сервисах не может быть общего кода. Т.е. настойчиво, в рамках одной системы, пишут компоненты, где вот тупо одно и то же несколько раз написано. А потому что сервис. А потому что в каком-то странном их воображении, так безопаснее, мол они независимые, у них только интерфейс.
Зато, когда приходит требование изменять, надо во всех модулях менять.
На счет генерации кода, я пользую, сам пишу генераторы или трансляторы. Но это когда никак иначе. Например, для какой-то своей ORM, надо классы для мапа в базу данных. Вообще, отношусь где-то так. Генерация лучше чем ничего, т.е. чем дублировать работу руками. То что там говнокод генерится, не страшно, главное что без ошибок. На то она и генерация, не для людей. Но, при этом, чаще всего, надо смотреть в сторону, а нет ли баги в архитектуре, раз нужна генерация. Потому что в первую очередь надо приводить саму архитектуру к такому виду, чтобы не нужно было дублировать что-либо, а генерация говорит о том, что автоматизировали рутину. Но наверное, ее вообще не должен код требовать.
Мне приходилось дублировать код в Angular. В нескольких компонентках код был схож на ~70%. Да, можно было схожий код запихнуть в отдельную компонетку и ее использовать во всех тех компонентках. Все это хорошо, но я понимал, что при первой же доработке любой их этих компоненток придется все переделывать. Там было логично оставить дублирующий код.
Спасибо большое за видео!)
Очень круто подаёте информацию!))
Большое вам спасибо за это видео.
Вот мы тут DRY обсуждаем, а в винде 10 две панели управления - вот вам и драй)
В точку. Сильно бесит
Это несколько вьюшек для одного объекта настройки. Значения настроек-то в обоих панелях не отличаются = принцип не нарушен.
@@ДорофеевСергей-г8р паттерн посредник
no
Дорофеев Сергей да-да, особенно список установленных программ один, да
Спасибо, очень понятно
В одном из проектов был бизнес леер. На основе его паблик метов, генерировался прокси, который вклчючал в себя логирование, откат трансакций, выполнение на другом потоке и многое другое. Перегенерирование случалось когда изменялись сигнатуры публичных методов. Вот для чего это нужно. И работало все как часы.
Вот вам еще пример автогенерации, который мне кажеться очень крут. При добавлении обектов, генерируются их билдеры, спомощью которых, можно легко создать нужный объект и написать тест.
Про генерацию кода - можно поспорить, а лучше послушать мнение от Сергея по поводу DSL(Domain Specific Language).
Иногда проще разработать небольшой язык и описать систему на нем, а далее сгененрировать код на общем языке(Java, C# и тд)
У JetBrains прям целая платформа есть MPS для этого
Обычно DSL понятен не только программисту, но и аналитику, тестеру, клиенту. В идеале сами требования транслируются прямо в код на общем языке
Ждем видео по DSL
Дублирование в легаси может появиться не с пустого места и решать какие-то проблемы. В частности при переходе/миграции между разными платформами часто делают поэтапный переход с поддержкой двух параллельно развивающихся систем. Авто-генерация тоже не грех. Особенно, если генерация API идёт через JSON-схему. Это позволяет отвязать API от реализации на конкретном языке и платформе. Ещё дублирование может быть вызвано оптимизациями запросов в БД, либо потребностью хранить в истории операций дополнительную информацию, не относящимися к самой операции (например, баланс счёта до и после операции, а не только сумму списания/зачисления), тоже самое и про дублирующиеся проверки на фронте и бэке.
Михаил Братухин примерно то же самое хотел написать. Как правило все эти дубляжи не просто так берутся.
Сергей, благодарю!
Прекрасный принцип и другое название SSO (single source of truth) ему очень подходит. Недавно столкнулся, когда в двух местах в программе у меня генерился GUID и я не понимал, а почему на определённом этапе у меня в базе в Redis данные начали задваиваться и вот после долгого дебага я выяснил, что генерация нового ГУИДА происходила в двух местах. Очень важный принцип, с которым столкнулся при довольно сложных обстоятельствах.
сергей: DRY
субтитры: ✨ Dior ✨
ахаха
Вот кстати на счёт изменение кода во всех местах - это не всегда так. Очень часто бывает так что изменение нужно только в одном месте (по разным причинам, но зачастую потому что это другая часть программы и мы не хотим ее трогать)
Сергей, ещё интересно было бы про Code Smell посмотреть. Википедия википедией, но ваши объяснения с примерами из жизни/опыта прекрасны.
Отличное видео.
Ещё пример нарушения dry - когда один и тот же модуль написан на разных языках, например под процессор и под видеокарту. Не всегда удаётся эти две имплементации как-то обобщить
На клиенте и на сервере можно сделать единые валидационные правила. Fluent Validation в помощь, достаточно лишь вызывать метод validate(model);
А если клиент и сервер пилят разные организации? Это довольно часто случается. У нас, к примеру, фронт пилят партнеры (у каждого свои команды и инструменты). А мы пилим серверную часть. Валидацию пишем так, будто клиент на своей стороне ничего не проверяет. Но надеемся, что какие-то данные они все же проверяют, прежде чем отправить запрос нам =)
Еще пример возможно нарушающий DRY, это CQRS + ES и построение представлений в отдельной бд, то есть данные в итоге имеют разную структуру но по факту повторяются.
Автогенерация частенько нужна в сетевых протоколах между разными языками, и должна производится на этапе сборки проекта, а кодеген не должен отдаваться под СКВ, это просто промежуточный артефакт сборки (ну, если мы рассматриваем систему нормальных людей).
Иногда кодеген нужен и для всякого сетевого транспорта низкого уровня в рамках одного языка, когда нужны сложные взаимодействия и нужно быстродействие, поэтому никакого доступа к рефлекшну и подобных вещей допускать нельзя, а хочется всякие данные прямо таки упаковывать поБИТно в поток, при этом описывая свои данные по-человечески, удобными декораторами и т.п.
Естественно, сгенеренный код НЕ меняется вручную НИКОГДА. Если нужно расширить его функционал, нужно расширять саму кодо-генерацию. Однако кейсы, когда это действительно нужно - есть.
было бы интересно посмотреть на примеры кода
Здравствуйте, Сергей. А что по поводу автогенерации кода в Entity Framework - Database First?
11:15
Сергей: "Монолит - хорошая полезная штука"
Где-то в далеке послышались злые звуки Соера
где-то в высоте..
Что думаете по поводу дубликации кода в DTO модели и более тяжелой ее версии для юая?
интересно было бы услышать мнение о таких принципах разработки как TDD, и возможно других, связанных с тестированием.
Про генерацию 👍👍👍👍👍 Наболело
Писал бакалаврскую по микросервисам, было бы интересно посмотреть как в монолите можно решить те проблемы, которые привели к микросервисам
Супер, фисташковые обои!
Очень нравятся видео этого автора, но вот не соглашусь с тем, что если код повторяется, то его нужно обязательно натянуть на DRY. Очень частый случай, в моей практике, когда начинаешь писать код (проект или компонент еще молодой и не оброс деталями). Коды очень похожи, повторяются некоторые шаги, но есть и различия. Прежде чем начинать делить, дробить чтобы соблюсти DRY нужно проаналазировать причины для изменения (как раз SRP) если код будет меняться с разной скоростью, если он будет меняться по разным причинам и в будущем еще и планируется, что его будут поддерживать разные команды со своими ТЗ, то беспрекословное следование принципу DRY очень усложняет развитие. В какой то книге я даже читала что этот случай называется: случайное дублирование. И ни раз я сталкивалась с ситуацией когда на начальном этапе коды очень схожи, их выносят в переиспользуемый блок, а потом начинается прирастание всякими if else. И проблемами со слиянием.И еще неприятнее: если нарушается вариантность при поддержке разными командами. Может, конечно я лишь подтвердила мысль обозначенную в последнем разделе видео. Если так, то извиняюсь
полиморфизм. паттерны и т.д. - вас спасут
Щодо генерації коду, я б не був таким категоричним. Ми на проєктах використовуємо typescript generator, який генерує з java DTO їх аналоги в typescript. Нічого поганого в тому нема, хоч і наш фронт-енд ПОВНІСТЮ залежить від згенерованих класів. Ніяких проблем з тим нема, навіть більше того, то нас береже від помилок з літерувками.
Другий приклад. Ми мали проєкт, де була купа табличок, в яких була купа фільтрів. Але була вимога до нашого API, що практично кожен метод який повертав дані для таблички, мав піти продубльований, щоб він ще й повертав ті самі дані в CVS файлі. Ми написали модуль, який генерував контроллери, в яких були ті самі методи, але з суфіксом '.../csv'. Код там був так собі, але зате ми скоротили кодову базу на 30%.
Вы про DRY в ДБ говорите. Про денормализацию слышали? Дублирование данных допустимо, если есть причины. Более того, нарушение Драй допустимо и в коде. Эти принципы не высечены в фундаменте разработки. Есть случаи когда дублировать код вполне допустимо. Так как переиспользуемый функционал может расширяться и спустя время вырастать в монстра. Updated...
Принципы в программировании никогда не вынесены в камне. Вы можете от них отклоняться. Принцип нужен, чтобы подсказать, где надо задуматься.
@@jewgenijmoldawski3306 так и я об этом. Но ведь в видео говорят, что нельзя дублировать данные по таблицам. Можно забыть об апдейте и тп...
Andrew Reznik, мне, как новичку, это видео полезно. Лучше ведь начать обучение с тем подходом, который пригодится в 80% случаях. Сергей говорит о том, что есть исключения.
Andrew Reznik, уверен в том, что он знает про денормализацию.
Но зачем это подавляющему большинству новичков?
Сергей Спасибо за видео. Какой тип паттерна архитектуры программного обеспечения можно использовать для (DRY). Пожалуйста, пример с открытым исходным кодом
Про монолиты тоже прослушал бы
Real time играм, которые интерполируют на клиенте пока сервер не ответил, не обязательно нарушать принцип dry. Принцип dry про непереписывание кода дважды. Но один и тот же код два раза в двух местах исполнять вполне нормальо ничего не нарушая. Просто его нужно вынести в переиспользунмый модуль. Некоторые высокоуровневые сетевые фреймворки в некоторых игровых движках типа Unet в Unity вообще позволяют не думать сервер ты или клиент, ты просто пишешь что происходит в общем, а дальше все само разделяется (ок, это слегка упрощение конечно).
Если бэк и фронт на совсем разных технологиях, то тут дублирование логики нужно или действительно переписывать или брать/изобретать некие декларативки с генераторами кода. Типа как какой нибудь ProtoBuf. Если они есть конечно.
Можно для той же проверки использовать одни и те же регексы.
Следуя принципу DRY нужно не уходить совсем в фанатизм. Переиспользоваться должна логика, а не просто код. Если код похож, но является частью выполнения различных задач - это не кандидат на попытку куда-то его вынести.
Стало интересно: а распределенные базы данных - это нарушение принципа dry? Ведь одни и те же данные лежат в разных местах, плюс еще изза ошибок обмена или репликации могут не сходиться.
Можно пожалуйста в таком же формате про Закон Деметры.
@Sergey Nemchinskiy DRY - по-английски - ди-аа(эр)-вай (читайте по буквам), а лучше всё-таки "драй "
Багато корисного. Дякую.
Расскажите про монолит!!!
Здравствуйте, я Сергей Немчинский и я расскажу вам как не повторять каждый раз "Здравствуйте, я Сергей Немчинский" :-)
вот захочется Сергею сменить имя, после чего зайдёт в ютуб - а плейлист весь красный, придётся в каждом видео менять..
Постоянно вижу дублирование кода, в некоторых CMS большие куски кода дублируются десятки раз. Это очень плохо, т.к. они с этим живут десятки лет. Да и у меня это иногда само собой получается. А бывают случаи, когда более правильно скопировать метод и переписать часть функционала, и при этом не выносить общий кусок в третий метод. При этом получится 2 метода с частично дублированнм кодом.
Но дублированние данных - это скорее нонсенс.
Запишите, пожалуйста, почему обычно монолит лучше микросервисов.
Студия шикарная
Про монолит интересно!
Сергей, а как быть если генерирование кода используется для проектов на нескольких языках? Скажем есть firmware на CPP и GUI на JAVA- и там и там одинаковые сущности с одинаковым поведением, генерация позволяет синхронизировать изменения в описании сущности сразу в 2 языках.
Хочу видео Монолит vs Микросервисы.
В этой самой книге, которую вы упоминаете (The Pragmatic Programmer), есть глава о том, что надо использовать автогенерацию кода). Вроде в разделе The Basic Tools. Книга в целом хорошая, но местами устарела. А ваш видос - это лайк!
Пример с табличками плохой. Хранилища данных часто создаются не так, чтоб программистам было удобно, а чтоб запросы и BI приложения быстро работали. Если очень нужно, то архитектор данных вполне может разместить те-же данные в нескольких таблицах. Не говорю что это прямо хорошо с точки зрения программиста, скорее о том, что так часто бывает.
Хочу видео про монолит
Услышал ваше мнение о кодогенерации, однако, небезизвестный Алан Кей сотоварищи продвигает STEPS, система с иерархической кодогенерацией. Каково ваше мнение об этой системе?
По поводу монолита и микросервиса, пролейте свет для малоопытных пожалуйста)
Давай делай про монолит, ждем
srp не задевает dry никак. srp это когда
fun doStuff() {
// generating stuff
...
...
// processing stuff
...
...
}
никаких дупликаций нет, но один метод выполняет несколько шагов (и хорошо, когда они никак не пересекаются, а то они могут смешаться, могут одни переменные из прошлого шага уходить в следующий, и столько всего ещё может быть).
хороший вариант будет таким
fun doStuff() {
val stuff = generateStuff()
processStuff(stuff)
}
такой код становится понятным и читаемым без комментариев (которые к слову зачастую тоже ошибки, комментарии стоит делать только у методов, но не у строчек кода, если функция pure, то комментарий к функции должен всё объяснять)
часто srp всякие геймдевы нарушают, которые не особо заботятся о кодстиле и сначала генерят локацию, а потом расставляют на ней каких-нибудь человечков, в лучшем случае, добавляя комментарии
Здравствуйте. Есть у меня такой вопрос.
Нарушает ли (или имеет ли отношение к) принципы DRY такой кусок кода.
this.variableA.variableAA = someValue
this.variableA.variableAB = someValue2
this.variableA.variableAC = someValue3
this.variableA.variableAD = someValue4
Вопрос в том должна ли бить вынесена this.variableA в отдельную переменную во избежание дубликаций
val myVariable = this.variableA
myVariable..variableAA = someValue
...
если база хранится в одной базе "долгого хранения", а для быстрого поиска в виде дерева в другой БД, реалтайм. нарушение?
если сделано осознанно из-за ограничения по времени выполнения запроса. запись в обе БД из одного скрипта.
одна и та же логика для валидации на фронте и на бэке, логика над данными в актуальной системе и в миграции (которая валидна на какой то момент времени только, а дальше ее могут менять). код, оптимизированный на что-то в одном месте и в других местах общего вида код. на самом деле кучу таких примеров можно найти и иногда копи-паста лучше чем упоротый dry в вакууме. нету универсального подхода) все эти подходы о которых идет речь это скорее то к чему следует стремиться, но оно никогда не работает на практике в его стерильном определении
Да, и я про то-же. Если есть система, которая генерирует классы/методы, время ограничено, бьюджет так-же, дальнейшее развитие и доработка очень маловероятны, то смысла не имеет рефакторить такой проект. Утверждение, что дублирование кода недопустимо - верно только для дорогих систем с длительной поддержкой и разработкой. Для одноразовых дешевых поделок (которых большиснтво в Вебе) это не верно.
@@Merk462 одноразовые дешевые поделки вообще писать смысла нет. Берется какой-нибудь Salesforce или Bitrix или вообще Wordpress и тупо натягивается на клиентский дизайн-макет. Или даже тупо покупается готовый шаблон. Для этого даже прогер не нужен.
@@homo-ergaster Менеджер, угадал?
@@Merk462 хреновый из тебя экстрасенс
я за монолит!
Крассава :) Осталось ещё YAGNI
Монолит интересно, ждем видео.
Расскажите про монолит
Проблема в том, что в рамках одного языка программирования оно не работает даже для одного проекта , не говоря о наследовании между разными проектами.
Как пример, возьмите какую-нибудь средненькую поделку с вебом, и внимательно посчитайте сколько одну и ту же конепцию переписываете на яве, жаббаскрипте, sql/хранимки/констрейнты, сериализации, формы/вьюхи, для мобилы, в документации,..
Потом добавьте пару заказчиков с перламутновыми пуговицами, миграните на соседний фреймворк или найдите ошибку в дизайне...
Именно про это и была фраза про автогенерацию - без выхода на метауровень, на уровень абстракции моделей и дизайна ПО, DRY нереализуем
При программировании на видеокартах бывает быстрее именно скопировать код в память видеокарты и заново рассчитать, чем обращаться к коду в оперативную память через медленные шины.
И если, например, в микроконтроллере мало памяти, то писать несколько функций, выполняющих похожие вычисления, пусть даже для разных задач - расточительство.
Для низкоуровневых программистов и микроконтроллерщиков все эти советы не работают.
Я об этом вообще-то в ролике и говорил. Вы его смотрели?
@@SergeyNemchinskiy Где? Прочтите "Повесть об одном байте". Вам понравится ))))
Или например, CFX-расчёты, когда обрабатываются многомиллиардные массивы данных, и дополнительная строчка кода приводит к дополнительному месяцу вычислений, и все эти ваши ООП вылетают, как слепые котята.
Советы для программистов офиснопланктонных программ, не более того.
"на моем компе работает" (С)
@@acd2377 студентов? неееет. Это любой, кто делает некую деятельность в коллективе, где в итоге должны объединить всю вашу работу ещё с кем-то
А ведь у меня в универе реально были такие случаи, но только с файлами Microsoft Office (к примеру, на моём компе документ отображается правильно, а на компах в универе нет)
Спасибо за обзор, Сергей.
Не согласен с принципом - нужно или не нужно дублировать данные - если это дает прирост производительности к их чтению-записи на больших объемах - дублировать (кусками) - это решение.
Например, 1С основана на принципе дублирования данных. Когда в базе за месяц миллион документов создаются, то любое чтение-запись этого миллиона займет неделю.
Это уже кэш, который хорошая система автоматически должна генерить и поддерживать до актуального состояния
про дублирование данных - да очень банально. Взял данные из одного источника - раздал их по API - вот тебе и дублирование =).
Какой-то второй консьюмер оперся на копию данных, решил срастить их с третьими данными, и может оказаться что копия еще не в синке, и консьюмер не может срастить 1 с 2. По большому счету "пофиг", со временем все равно синканется, но как в той песне - "а что если нет?" =) Что если синк сломался по какой-то причине? =)
привет. 0:48 "я люблю говорить ди-ар-ай" - а разве спеллинг не должен быть ди-ар-вай ? DRY, звучит уже не так круто, как DRI, правда?
Вопрос, а что про модульность?
Тоесть если в моем проекте есть сущность "Новости", и есть ... "Статьи", они очень похожи архитектурно, но предметно разные.
Если я выведу всё в переиспользование то изменение Новостей изменит Статьи, но если не переиспользовать то местами будет 1в1 одинаковый код.
Но вы же будете в рантайме создавать два разных экземпляра объектов, поэтому они будут жить своей независимой жизнью. А вот класс, который будет создавать объекты и для статей и для новостей будет один.
@@sterlo-x8z я к тому веду, что абстрактно - это разные сущности, и если две (и более) сущности будут зависеть от реализации (так совпало что логика в них одинаковая) то мы нарушаем DIP, и если придет программист Петя и поправит "новость" думая что поступает правильно, цепляет ещё и "статьи" и ему от тестирования приходит ошибка с левого модуля.
и т.о. модульность тоже нарушается (правим один модуль, не так работает другой)
Лайк за "нижний плечевой пояс". Орнул.
@sergey, если есть свичеры в андроид с другого языка, есть вариант найма в СПб, опыт на андроид не обезателен, надо только желание учить его)
Вы привели пример какого-то такого себе программиста и его проект с базой данных,
- - - -> где информация дублируется,
- - - - - - - -> но в коде надо вручную вписывать два раза.
Может лучше просто написать подпрограмму, которая вставляет в два места? [face palm]
на самом деле макросы и шаблоны м с++ и есть автогенерация кода. зачем писать одинаковую имплементацию для разных типов данных, например матрица от дабл или флоат.
так что да. шаблоны как раз для DRY
"Автогерерация ... срань господня" - плюсую =)
Давай про копролит, ой, про монолит
В реляционных базах данных ж 1НФ 2НФ ... бойса-кодда итд, интересно много л ли программистов про это знает
почему "Ди-Ар-Ай" ? Никакой "ай" на конце нет. Уж лучше "Драй", вряд ли вы говорите "Кей-Ай-Эс-Эс принцип"
Вот-вот. Раз уж на то пошло, 'Y' - 'уай', а не 'ай'
"Уай"
Надеюсь ты английский прокачаешь до уровня С1, чтобы понимать эти тонкости произношения.
Сергей получше тебя знает произношение английской буквы "Y" и применяет "проглатывание" звука.
Про элизию почитай.
Чтобы тебе было проще понять это, начни с изучения элизии постфиксов "ся" и "сь" в русском языке.
@@vlaih0 ок, я не против, главное, чтобы вы проглатывание не применяли (:
@@MrPavel0 шутки уровня интима... Да вы только что подтвердили ваше очень скудное умственное развитие. Всего доброго.
@@vlaih0 прощайте
Дублирование кода не отменяет его понимания, если все четко осознается и применяется в своем софте не может быть ни каких проблем, ну зачем тратить время на написание функции еще раз ? Есть входные параметры и нужное на выходе, для чего писать самому тоже самое и тратить время ? Возможно для самоутверждения, с этим я соглашусь, но это будет влиять на время написания кода, реально смысла в этом ни какого нет.
Прокладки используют те кто не умеет создать подобное на оригинале.
Главное соблюдая DRY не упускать из виду DRAE (Don't repeat anyone else).
Ну и печалька, если прилетает проект на Go с монгой в качестве базы... У создателей этих поделок явно аллергия на DRY
А что там не так? Просто никогда не сталкивался с Go, тем более в связке с монгой.
А так на монгу сейчас многие хотят переехать. Вернее многие хотят 2 базы - что-то SQL-based как основная и еще склад документов всяких на монге.
@@homo-ergaster с go основная проблема в почти полном отсутствии полиморфизма, есть только некое подобие на базе утиной типизации. В неопытных руках, а на go таких большинство, код превращается в лютую кашу, где одно и то же написано в десятке мест. Да и в опытных руках, этот ад заменяется кодогенерацией, что не на много лучше. Кстати, о руках, на go 2 типа разрабов - совсем неопытные юнцы, пришедшие в сферу как правило из-за денег (как итог быстро сливаются), либо нормальные спецы, но пришедшие с других ЯП, каждый со своим подходом и пришедшие сюда от какой-либо безысходности...
Ну и еще про DRY в go, просто попробуйте посчитать количество if err != nil в любом проекте...
Что касательно монги, все будет ок, если данные не сильно связаны, но я таких данных пока еще не видел (если они относятся к одному бизнесу конечно), добавим сюда полную бесструктурность базы - и вот, каждый городит кто во что горазд. Нормальных джойнов тоже нет (опять же в последних версиях добавили некое подобие outer join в агрегацию, но ситуацию не спасает). Ну и часто встречал, "мы хотим именно монгу, ибо она у нас уже есть, а ваш посгрес (или чтото более подходящие) мы админить не умеем"...
В принципе, что монга, что go неплохо себя показывают при прототипировании, когда на них делаешь что-то с нуля, оно действительно выходит быстрее. Но проблема большинства менеджеров/продактов, что они не выбрасывают прототипы после +/- удачного экспиримента, не понимая, что берут время в кредит под огромный %... А поддерживать кашу в коде на go и в данных в монге тот еще ад...
@@ДмитрийБеляев-ъ1з понятно. Тяжело вам там )
Забавно, смотрел конференцию основателя Nginx который против DRY. По крайней мере в администрировании nginx
Лайк за келих )
Сергей, у вас отличные видео, и подача, и материал - на высоте, более того - вы в теме преподавания, а значит вы знаете цену самосовершенствованию, к тому же у вас учатся люди. Ваши ошибки, даже мелкие - осядут в головах тех, кто вас слушает, даже такая мелочь, как произношение DRY.
Вы выкладываете видео на платформе, на которой есть носители практически любого языка.
Написав “don’t repeat yourself” в поиске, можно получить однозначный ответ - как правильно произносить термин, принесенный из другого языка, если термин не авторский - вряд ли есть место авторскому произношению.