У меня другие наблюдения. С одной стороны простой код действительно стал безопасней из коробки и поэтому простым девелоперам сосредоточенным на бизнес логике стало легче писать на плюсах. С другой стороны есть такая категория девелоперов которые явно умнее среднего, но не достаточно, они то как раз герои пословицы горе от ума. Поясню, они достаточно умны, чтобы написать нетривиальный системный/библиотечный код который полон УБ, но работает почти всегда правильно. Ума написать такой же, но без УБ уже не хватает. Это часто проблемы в многопоточном программирование, безопасности памяти, исключений.
Такие люди создают код который приносит невероятного масштаба жопу. Починить(с учётом уже всех существующих юз кейсов) очень сложно, переписать на стандартные/надёжные решения очень дорого, т.к. они отличаются архитектурно/по ограничениям.
Так вот последние нововведения в плюсы вообще никак не помогает таким людям писать более безопасным образом. Атомики прекрасный новый неисчерпаемый кладезь УБ. Понять модель памяти с++ не реально, можно только простить. Написать тесты на код с атомиками задача невероятной сложности. Да даже многопоточные тесты это 99,999% это тупо таймеры. Ни одна душенка в комитете даже не задумывается на эту тему - мы вам дали автомат, а технику безопасности сами как нибудь. Шаред поинтеры, до массового использования атомиков были проблемой номер 1, но атомики конечно победили с большим отрывом. Прекрасный дизайн шаред принтеров спустили в унитаз под названием ГЦ для бедных, только они не ГЦ и проблем создали намного больше чем решили. Теперь понять, что когда умирает в продуктовом коде решительно невозможно. Казалось бы в теории я и не должен, но в реальности ещё как должен.
Новое модное течение - рэнджи. Опять же казалось бы такая классная штука, но теперь рэнджи ради рэнджей везде и понять стало сложнее и тормозить стало больше. Ну спасибо чё.
То что делает комитет все нужно и действительно важно, но вы там почему то забываете писать много хороших примеров как пользоваться новыми игрушками, но ещё важнее написать как НЕ надо пользоваться ими. Где вашу мать техника безопасности на новые приблуды?
У вас тачанка УБ в примерах с player_actions. Что с мьютексом, что тем более с атомиками. Ну если с мьютексом там скорее всего просто опечатка и пример легко починить, то вариант с атомиками в принципе неверен. Несмотря на то что "все изменения" в данных будут видны их нельзя менять/читать одновременно из разных потоков. Может вы спутали пример с двойным буффером когда происходит переключения через атомик поинтер между тем в который пишем и тем из которого читаем, тогда бы это имело смысл, но строго для 2 потоков.
А ещё можно поступить точно так же, но проще - совершенно произвольно запретить на код ревью поднимать темы код стиля и сначало мягко объяснить нарушителем запрета, второй раз жёстко высушить и что то там ещё, а третий последний.
И внезапно люди научаются жить без линтеров, читать код в любом стиле и писать так как душе нравится. Оставить можно только совсем базовые принципы именования и то сделать упор, но то как не надо именовать, но не навязывать жёстко как надо.
Консистентнгсть это миф, у вас в коде всегда смесь, ваш код, стандартная библиотека, фрэймворк, и поверх ещё чужие библиотеки и каждый в своем стиле и нужно часто все это в одном месте/функции. И как то все живут и не жужат, а тут видители колега совсем берега потерял в моей песочнице ссыт не по-моему уставу.
Ну можно и так сказать, но есть более общеупотребительное слово, вы сразу поймете о чем речь если типом х и у будет строка. Я просто взял простой и понятный код и переписал на рэнджи. Потом для проверка попросил кита подумать и объяснить что делает код, умный гад, думал долго, но ответил правильно, но что ещё важнее он показал, что моя прямая попытка смапать на рэнджи работает не совсем так как оригинальный код. В оригинале find_first_not_of, что не тоже самое что и в примере выше. Работает правильно если у содержит 1 элемент, но в оригинале у меня стандартный набор элементов для этого алгоритма в качестве дефолта идет. А написать на рэнджах правильно низя т.к. нету там find_first_not_of. Не подвезли даже в с++26. Можно конечно извернуться и написать через find_if_not + contains/any_of или find_first_if + none_of, но и так уже сложно читать.
Так давайте проверим, алгоритмы говорите, читабельные говорите и все такое блабоабла.
auto xxx(auto& x, auto& y){
using namespace std::ranges;
auto begin = find_first_of(x, y, not_equal_to{});
auto end = find_first_of(subrange(begin, x.end()) | views::reverse, y, not_equal_to{}).base();
return subrange{ begin, end };
}
Назвались груздем полезайте в кузовок. Рэнджи ещё более самые супер пупер лучшие алгоритмы, авто везде не просто так, а что бы алгоритм был максимально дженерик и компилятор/рэнджестроители могли показать максимальную оптимизацию под конкретно ваш случай. Там конечно можно ещё концептов на х, у навесить для пущей пидидитости, но это только добавит шума и не облегчит ответ на вопрос. Что делает эта функция одним словом? Я специально заменил нормальные имена на х, у ибо тогда станет очевидно.
Гусары не читерить, ллмы трёх метровой палкой не трогать. В идеале сипипиреф тоже не открывать если вы за алгоритмы должны и так понять.
Вопрос со звёздочкой насколько производителен такой код? Годен для геймдева?
Так хорошо, а что вы ожидали? Точнее все работает в соответствии со спекой https://en.cppreference.com/w/cpp/container/vector/erase Мне реально интересно какие у вас были ожидания от работы этого метода до того как вы разобрались с вопросом? Второй вопрос вызывающий интерес, когда вы разобрались как это работает почему вы решили написать об этом статью?
Мне кажется, несмотря на то, что вы разобрались как работает ирэйз вам все ещё не понятно почему спека на него именно такая (ну просто какие то деды решили, что так им удобней 100500 лет назад), а не так как вы ожидали. Я могу помочь вам разобраться почему спека именно такая, а не как вы ожидали.
К моему счастью, русский действительно не пригодился. Тот же МФТИ из статьи предлагает зачёт/не зачёт ну чтобы удостовериться, что абитуриент вообще понимает русский и может изъясняться на нем. А вот физика пригождается чуть ли не каждый день, но не по работе, а по жизни. Конкретный раздел - электричество, ну то которое совсем базовое - электротехника, закон ома вот это все. Механика изредка - в общем как раз школьный курс.
Все число дробилки которые я кодил или видел вообще не требует динамической аллокации, если точнее, то она конечно нужна т.к. размер стэка ресурс ограниченный. Все ж таки буфера алоциртся в хипе, но 1 раз перед началом расчетов. Поэтому фиолетово сколько у вас там потоков. Я не видел успешных число дробилок которые чё то динамически аллоцируют посреди рассчетов в таких количествах когда нужно думать об аллокаторах.
Динамическая аллокация жизненно необходима в событийных системах, но если нет жёстких требований по лэтенси то и стандартного аллокатора достаточно. А когда лэтенси важно то первым делом аллокации вообще выпиливают и только когда от них нельзя или дорого избавиться начинают думать над аллокатором.
В далёком 2006 мне надо было портировать очередную жей2эме игру на платформу где использовался с++. Все контора этим занималась - пост продакшн на мобилках тех времён. Не помню точно какая возможно это был Соник. Так вот на большинстве телефонов все работало норм, но была платформа где было медленно. Я залогировал (построил гистограмму) всех аллокаций, ну к моему счастью 95% были блоки на 12 байт. Ничего не зная про все эти типы аллокаторов я просто совместил блочный и фри лист, додуматься до этого не много ума надо. Метаданные (связный список свободных блоков) был размещен в самих блоках одинакового размера. Я сделал список на массиве и по сути указатель на следующий блок это индекс в массиве. Т.е. был большой массив блоков по 12 байт, когда блоки свободны они хранили индекс следующего блока, а когда заняты какие-то данные.
Померял сколько нужно блоков, ну как померял увеличивал размер пула по фибоначи пока не перестало крашится потом увеличил ещё разок на всякий случай и успокоился. Игра стала летать. Т.к. я заранее сделал размер пула точно больше чем нужно блоков, то даже выкинул проверку на нет блоков.
С тех пор никогда больше мне не требовалось заниматься подобной магией, кроме трэйдинга по причине лоу лэтенси требований. Так вот все эти аллокаторы нужны либо в играх либо в трэйдинге, звук иногда, но там можно просто все заранее преаллоцировать. Короче в обычной жизни даже стандартного аллокатора хватает, не говоря о том что есть джейемалок если обычный не устраивает.
Большинство проблем надумано зелёной повесткой. Суммы ежегодных потерь вообще не имеют смысла и практически одной природы с недополученной прибылью, с той лишь разницей что "потрачены". Потери не является чем то объективно необходимым, а ограничены сверху лишь беджетом, а с низу жадностью зеленых. Но не все конечно.
Реальная проблема это кролики и прочие вредители. Что такое вредитель в этом контексте? Не тот кого называют зелёные вредителями, а тот кто реально мешает ЛЮДЯМ. Зелёные во вредители записывают вообще всех не эндемиков (включая самих людей хехе, но не оч любят об этом говорить и афишировать).
Планете/природе вообще фиолетово кто и каким образом куда попал, не смог приспособиться - ну сдохни че, свято место пусто не бывает. А зелёные это настоящие вредители, мало того, что они тратят любое количество денег на безуспешное решение "проблем" и само собой хотят ещё больше в следующем году, ну так как в этом не получилось и надо просто больше ну и зациклить эту схему. Так они ещё и закрывают доступ к рэнджам для туризма, т.е. люди с налогов которых все это шоу устраиваются не могут пойти и посмотреть на этих сраных недобидытых бедненьких эндэмиков.
Это очень удобно и повышает прозрачность работы зеленых, ну чё победили Х в этом году - ну не совсем, ну ладно, а чё там с У которых мы и защищаем уничтожением Х? Стало лучше, хорошо, а посмотреть можно - низя или нахер, глупых вопросов почему нельзя не задавай и вообще дай ещё денег. Вот так выглядит деятельность зелёных для меня. Я из НЗ здесь практически такой же дибилизм.
Потравили кроликов, ёжиков, и котов в городских парках/местах для прогулок (там где они вот вообще никому не мешают) ради сраных птичек. С собаками гулять нельзя почти везде, кроме пляжей и то не всех и некоторых специально отведенных мест. Каури (деревяшечка такая, красивая большая) тут спасают уже десятки лет от грибка, и вот по этому поводу запрещено гулять почти по всем рэнджам где оно растёт.
С поссумами вообще прикол вышел, они объявлены пестом ибо инвазивные и все такое якобы воедят птицам т.к. едят яйца. Завезены из дружественной Австралии для борьбы с кроликами - шизофрения во всей красе. Там то они не инвазивные и защищаются, а тут отстреливаются. Но да ладно, ёлки-палки которые сосны тоже объявлены пестом, т.к. быстро растут и мешают местной флоре. Так вот цимес, недавно выяснилось, что поссумы жрут шишки и борются с ёлками как теперь быть со статусом поссумов не знают то ли все ещё пест то ли уже не пест.
Мораль сей сказки проста, завезли и завезли не такая уж и проблема, ЭКО система сама придет в равновесие возможно не скоро, но придет. Решать надо (тратить деньги) не на то что бы убивать одних во имя других (они сами разберутся кому жить, а кому нет), а на решение проблем которые мешают ЛЮДЯМ. Главное во всем этом люди, а не пресловутое представление зелёных о том как правильно, а как нет.
Бесплатный демо доступ на 15 минут и автодозвон чтобы таких же демо халявщиков обгонять, а через месяц звездюли от родителей за счёт на превышение минут на месяц. Потом тоже самое, но не более раза в день, что бы лимиты не нарушить.
У меня был скачан мсдн и все нужные книги в оцифрованной версии, а самые нужные - Страуструп - в бумаге.
Можно какой-нибудь пример, чтобы я лучше понимал контекст?
Ну например вы реализуете сэтабл синглтон. В продакшеге у вас один код который его сетит и он всегда исполняется при инициализации, а в тестах вы резетете его после/перед каждым тестом. Да конечно можно и функцию резет в самом типе реализовать, но она не нужна в продакшнене, а опшионал ее и так реализует.
Я как раз на плюсах и пишу там помимо * и -> есть еще и валью и валью_ор и в 23 ещё и прочие функциональные зены и элсы подвезли. Так что все там есть чтобы писать без уб. Но уб наше все конечно куда ж без него. Я чиню говнокод и на плюсах (прод) и на питоне (авто тесты) и в ява скрипте (кумл/гуй). Конечно плюсы 99% моего времени, но я не заметил каких то принципиальных отличий ну опять же кроме самого важного для плюсов - весь спектр уб. Ну т.е. да на плюсах гавнокода я вижу сильно больше, но он это интересней что ли.
А с проверкой один раз в мэйне может не получится опять же если поодакшен по бизнес логике требует опшионал, а если не требует то и проверять явно ничего не надо, а вместо этого использовать функции/апи без уб.
Ну почему же так радикально? Например опшионал может быть нужен только для тестов, а не в продакшене, тогда нет нужды ни в каких проверках, а если все таки вдруг кто то что поломал в продакшене и синглтон пуст при первом использовании то доступ к значению опшионала кинет исключение или терминирует программу кому как нравится.
Если же опшионал на самом деле нужен в продакшнене то ваша замена с конструктором не эквивалентна т.к. проверку на пусто кто то где то всё ж таки должен делать.
В поддержку предыдущего оратора и чтобы было чуть более понятно на примере. Квадрат прекрасно сабклассирует прямоугольник если интерфейс прямоугольника не содержит инплэйс мутаторов.
Тогда не составит труда корректно с точки зрения лсп реализовать перегрузку в сабклассе квадрат. При этом квадрат может иметь свои специфичные методы которые возвращают квадрат, что бы можно было и дальше сабклассировать при необходимости.
Тут конечно может возникнуть оверхед на то чтобы боксить возвращаемые значения в зависимости от языка и вашей реализации.
Но тут главное какую задачу решаем, если это векторный редактор и вы мышкой тянете сторону квадрата, то наверное вы хотите чтобы он квадратом и остался и тогда можно делать мутабельную версию которая при изменении длины и ширину поменяет, а вот версия выше юзеру не понравится т.к. квадрат мгновенно превратится в прямоугольник. Просто в мутабельной версии вы должны каким то образом выразить (хоть в документации) что изменение длины не подразумевает неизменность ширины и тогда нет никаких проблем с лсп и в мутабельной версии. Можно даже оба подхода совместить и иметь визЛенч и сэтЛенч.
Ответ очевиден, синглтон лучше тем, что не требует передачи контекста/себя. Вот вы сосласиь на DI, а разве инжекция не требует того самого ну этого как же его, а вот синглтона?
Есть способы обойти ВСЕ перечисленные проблемы и остаться синглтоном, ну собственно DI это и подтверждает, но можно и самому сделать если надо.
Вот когда появится потребность мульти ботов или сикуреэс, вот тогда и перепишем с синглтона на 2(М) синглтонов просто разного типа. А с тестами все не просто, а элементарно - сделайте уже наконец функцию резет вашему синглтону или ещё лучше реализуейте сэтабл синглтон и тогда вот это поворот можно даже хоть мокать хоть фэйкать его как угодно.
А синглтонов в коде полно, например ОС апи - синглтон хоть и явно никакого объекта не требует, логирование, стандартные консольные потоки ввода/вывода, ФС, реестр и т.д.
Синглтон надо уметь готовить, а не критиковать. Если чего то стадо действительно больше одного ну просто уйдете от синглтона позже, да может быть тяжело и больно, но не ужас ужас ужас как пытается об этом сказать автор.
Плюс появляется многопоточность даже в самых простых приложениях, а это ведёт к багам
Это зависит от того как вы сделаете. Вот вы тут критикует курлу говоря, что там асинхронность с боку, но там как раз сделано так что вы сами управляете пулом потоков. Там очередь, а на чем ее крутить решает юзер код. Точно также можно сделать таски обработки запросов, а в апи выставляется функция запуска очереди. В простых случаях эта функция вызывается на одном потоке, хотите в главном как у вас в примере хотите в отдельном. В сложных случаях вызывается несколько раз из нескольких потоков - масштабирование.
у курла другие задачи, при этом там гораздо больше обработки ввиду того что легаси и гораздо меньше гибкости, а у нас своё решение, где мы можем творить что угодно под нашу конкретную задачу
Какие задачи решает курл я вроде бы как знаю, и меня удивило, что по вашему мнению он не покрывает хттп2 транспорт. Расскажите какие задачи решает ваша хттп2 реализация которые не решаются курлой? Какой такой гибкости вам не хватает?
И скачивания тоже CPM избегает, если вам это нужно. И если ваш проект уже подключает буст, то CPM возьмёт его из кеша
Да и обычный фетч контен можно сделать без скачивания только это все костыли плюс брать что то из кеша возможно при соблюдении правил - сипиэм должен быть последним и предыдущий подход должен юзать фаинд пэкедж. Ну для буста это скорее исключение если кто то не через фаинд его подключает, а вот много других либ далеко не всегда предоставляют симэйк скрипт и там уже может не получиться у сипиэма найти что то в кешах. В общем мне кажется, что вы рано считаете, что основная проблема с++ решена для вашей либы. Если вдруг у вас будет какое то количество сторонних использований и никто не будет жаловаться тогда да решена.
корутины здесь потому, что это единственный и лучший способ организации асинхронного кода.
Я не очень понимаю, что вы хотите этим сказать. Вы же не утверждаете, что до с++ 20 на этом языке невозможно было реализовать асинхронность? Понятие лучший тоже никак не раскрыто, а если вы на самом деле считаете, что корутины это единственный способ, то качественная оценка лучший не имеет смысла. Это как первый элемент в очереди из одного элемента он же и последний - худший.
Насчёт транспорта я не понял, что прибили? Вы хотели по grpc ходить в телеграм?
Я хочу заменить вашу хттп2 + азию на курлу или культю не меняя код апи.
в случае парсинга, я кроме boost json больше не знаю ни одной библиотеки json поддерживающей потоковый парсинг
Если вы про SAX парсер то например nlohmann::json умеет такое.
не понял тут
Там сложно объяснить простым комментом поэтому я не буду вдаваться в подробности. Есть ещё одна альтернатива вашей архитектуре, можно парсить хтмл от телеги и генерить какой нибудь стандартный рест апи файл, а уже потом используя стандартные генераторы реста получить готовую либу не только на с++, но и для других языков. Мы например так генерим с++ транспорт культевый для своих рестов, где то мне попадались генераторы и на другие реализации сети. Очевидно эта работа (по предоставлению стандартного реста) должна быть сделана самой телегой, но раз они не сделали то это было бы наиболее полезно.
у нас библиотека итак разбита на множество частей.
Есть разница между разбивкой библиотеки на части/фичи и отделение каждой части в независимую библиотеку. Разбивка на библиотеки сложнее, но как вы говорите гибче. Когда у вас разбивка идёт на фичи, то сборка/зависимости управляются единообразно в родной либе, а когда разбивка на либы, то необходимо предоставить интерфейсы к зависимостям на уровне сборки в каждой либо - больше работы/сложнее, но позволяет легче интегрировать только необходимые части в существующие проекты.
Я пишу с телефона и это очень больно, дальше идут параграфы не совсем согласованные между собой так как написаны они были в разном порядке, а это вступление вообще самым последним, чтобы хоть как-то смягчить удивление от моего коммента.
Скажите, а чем не устраивает классический вариант когда из главного потока синхронно в цикле полим и запускаем синхронную джобу на пуле потоков которая занимается обработкой?
Насчёт хттп2, чем вас курла не устроила?
На буст у многих аллергия по причине монструозности и отвратительной документации. Имхо делать его зависимостью в либе это вообще самое последнее средство когда по-другому вообще никак. Т.е. для меня это сразу красный флаг и четкое нет вашей либе, но я понимаю что художник вы и вам так красиво.
Вот например у нас в проекте тоже есть буст и если добавить вашу библиотеку то потенциально может появиться конфликт версий буста на ровном месте, потому что мы обновляем его только когда приспичит. И зачем нам этот головняк с разными версиями буста, я понимаю, что скорее всего никаких проблем не будет, но все же?
Если я правильно понял то у вас код пляшет от с++ структур по ним генерится сериализация в жисон, но есть и другой путь, вы можете генерить жисон, а потом из него генерить с++ структуры. Не уверен, что это не мое личное определение/понимание, но я называю этот подход обратным орм. Имхо сильно проще чем обычный орм когда источником правды служит конечный язык, а не скул/жисон. В идеале вам вообще не нужна билд зависимость от жисон библиотеки, вместо этого можно сгенерировать прям код сериализации только для ваших структур используя жисон библиотеку как дев зависимость в терминах раста, но честно я не знаю насколько это осуществимо на плюсах сегодня.
Все до этого существующие библиотеки телеграм ботов на С++ требовали установить зависимости вручную.
Имхо только так и надо. Вот например у нас используется йокто, а тамошние художники решили, что ходить в сеть во время сборки это вредно для здоровья. И все эти ваши фетч контенты с сипиэмами не работают, надо костыли делать. Опять же в экосистеме раста этот вопрос решен красиво, библиотека бьётся на более мелкие, т.е. например есть только та что генерит ц++ апи который про жисоны ни сном ни духом не знает, а просто отдает пэйлоад строкой , поверх уже сериализация в структуры и роутинг на команды, где то ещё будет подсос зависимостей из сипиэма в виде отдельной либы. А на границах интерфейсы. Зачем? Ну у нас и культя в проекте тоже есть и у нее тоже на любой вопрос свое решение и жисоны и сеть асинхронная имеются. В идеале я бы мог взять например ваш генератор апи и подставить свой транспорт потом распарсить жисон своей либой уже в свои структуры. Да это все сильно сложнее чем то что у вас, но зато намного проще комбится с существующими проектами. Ваша библиотека для написания бота отдельным приложением с ноля, а в существующий проект так просто как хочется не воткнется.
Корутины конечно модно и все такое, но ведь курла такая же асинхронная (как и культя), а если есть (а иначе нафига этот бот нужен) тяжёлая обработка то без пула потоков с джобами все равно не обойтись. Т.е. ваш демо/эхо бот точно также можно сделать с курлой в один поток, а что не демо так нужен пул все равно, так и зачем тогда эти корутины конкретно в этой либе? Я могу понять выбор корутин как достаточно универсальный интерфейс для транспорта, но вы транспорт гвоздями прибили и заменить его нельзя, тогда зачем корутины?
Я не критикую, а хочу понять вашу мотивацию/цели/проблемы связанные с выбором именно такого дизайна библиотеки. Т.е. мне лично код примеров вообще не интересен был как и сама либа, а вот как вы принимали архитектурные решение было бы интересно почитать.
Мне кажется, что не существует бизнес проблем которые формулируются как
невозможно переиспользовать А в разных ситуациях (с разными реализациями Б)
Бизнес проблемы они больше про - стало больше пользователей чем раньше и система не тянет по производительности. Наши инженеры посмотрели и сказали что модуль Б не вывозит и его надо заменить на модуль Ц. Или наши заморские партнёры по доброте душевной больше не берут наши тугрики и надо заменить модуль Б на модуль Ц. Или наше отечественное руководство заботится о нашем бизнесе и наших пользователях и настоятельно просит использовать модуль Ц из белого списка вместо модуля Б. Или модуль Б был написан ещё древними греками по заветам самого Зевса, но последний сервер способный исполнять этот код запланирован в утиль и надо заменить на модуль Ц который может работать на наших серверах.
Бизнес проблема звучит так, что не возникает вопросов зачем мы хотим заменить Б на Ц, а вот инженерная задача не отвечает на вопрос зачем. Я не буду никого обманывать и сознаюсь что решать бизнес проблемы мне не интересно, а инженерные задачи интересно, но все же разница есть.
В любой из этих историй просто замена модуля Б на модуль Ц даже если он скрыт за абстракцией это утопия. Может ли помочь абстракция - да может, но может и наоборот немного помешать. Скорее всего абстракция больше поможет (немного) чем помешает, но будет мешать всю свою жизнь особенно если бизнес задача не возникнет. Т.е. платить за абстракцию мы будем всегда, а воспользоваться может и не удастся.
Если ваше бизнес решение с лёгкостью позволяет заменить базу данных на другую, то вероятно вам база данных в общем то избыточна и можно обойтись более простыми == дешёвыми средствами. Если транспорт можно с лёгкостью заменить на другой то опять же можно обойтись чем то более простым.
Мой поинт в том, что такое может быть, но я больше ожидаю такое от стартапа где эффективность не является конкурентным преимуществом и реализации скрытые за абстракцией можно менять просто, но я думаю и без абстракции их тоже можно заменить не сильно дороже потому что это стартап и/или эффективность не главное, но дороже да. Там где эффективность реализации это конкурентное преимущество я очень сильно не ожидаю таких чудес как просто замени Б на Ц и все готово я такого не встречал.
Это не значит что ДИП не нужен никогда это значит, что он нужен ИМХО только тогда когда для решения бизнес задачи вам надо иметь более одной реализации т.е. вам нужно использовать и модуль Б и модуль Ц вот тогда и нужно внедрять эти абстракции. Да я знаю есть ещё юнит тесты опять же ИМХО для бизнеса нужны не они, а функциональные тесты которым наличие абстракций ни как не помогает. Я сторонник фэйкания внешних зависимостей вместо мокания внутренних реализаций. Юнит тесты имхо идеальны для библиотек решающих конкретную инженерную проблему, а для бизнес логики/приложений предпочтительнее тесты функциональные.
Да конечно это все философия, стилистика, субъективная вкусовщина, но ведь статья про солид, а что это если не философия?
ПС если у вас 2 модуля рекурсивно зависят друг от друга то их разделение через 3 модуль не всегда то что нужно. Возможно их объединение в один модуль будет иметь больше практического смысла чем разделение любой ценой ради соблюдения каких то других философских принципов.
Я понимаю что разделение, навязывание структуры, введение ограничений предназначено для уменьшения энтропии системы, но это все имеет цену - когнитивную цену. Мой опыт говорит мне, что люди в целом любят рассуждать о красивых системах, но на практике те же самые люди принимают очень сабоптимальные решения, потому что командные цели, скрам, объективная когнетивная сложность красивых решений и не уверенность в своих способностях / страх облажаться давят сильнее чем чувство прекрасного. Лично я нахожу вкус и запах легаси спагетти кода вполне себе съедобным, и не очень люблю изысканную пишу гурманов. Мне главное, что бы дёшево и нажористо, а утонченные вкусы и эстетическая красота за дорого не очень привлекает, хотя на выходных пойдет для разнообразия.
У меня другие наблюдения. С одной стороны простой код действительно стал безопасней из коробки и поэтому простым девелоперам сосредоточенным на бизнес логике стало легче писать на плюсах. С другой стороны есть такая категория девелоперов которые явно умнее среднего, но не достаточно, они то как раз герои пословицы горе от ума. Поясню, они достаточно умны, чтобы написать нетривиальный системный/библиотечный код который полон УБ, но работает почти всегда правильно. Ума написать такой же, но без УБ уже не хватает. Это часто проблемы в многопоточном программирование, безопасности памяти, исключений.
Такие люди создают код который приносит невероятного масштаба жопу. Починить(с учётом уже всех существующих юз кейсов) очень сложно, переписать на стандартные/надёжные решения очень дорого, т.к. они отличаются архитектурно/по ограничениям.
Так вот последние нововведения в плюсы вообще никак не помогает таким людям писать более безопасным образом. Атомики прекрасный новый неисчерпаемый кладезь УБ. Понять модель памяти с++ не реально, можно только простить. Написать тесты на код с атомиками задача невероятной сложности. Да даже многопоточные тесты это 99,999% это тупо таймеры. Ни одна душенка в комитете даже не задумывается на эту тему - мы вам дали автомат, а технику безопасности сами как нибудь. Шаред поинтеры, до массового использования атомиков были проблемой номер 1, но атомики конечно победили с большим отрывом. Прекрасный дизайн шаред принтеров спустили в унитаз под названием ГЦ для бедных, только они не ГЦ и проблем создали намного больше чем решили. Теперь понять, что когда умирает в продуктовом коде решительно невозможно. Казалось бы в теории я и не должен, но в реальности ещё как должен.
Новое модное течение - рэнджи. Опять же казалось бы такая классная штука, но теперь рэнджи ради рэнджей везде и понять стало сложнее и тормозить стало больше. Ну спасибо чё.
То что делает комитет все нужно и действительно важно, но вы там почему то забываете писать много хороших примеров как пользоваться новыми игрушками, но ещё важнее написать как НЕ надо пользоваться ими. Где вашу мать техника безопасности на новые приблуды?
Ничего не понятно про этот релокэйт, но очень интересно.
Вопрос, это вообще ок или это ещё один способ написать УБ? Если ок, то будет ли вызван деструктор для х? А что насчёт у был не пустым?
У вас
тачанкаУБ в примерах с player_actions. Что с мьютексом, что тем более с атомиками. Ну если с мьютексом там скорее всего просто опечатка и пример легко починить, то вариант с атомиками в принципе неверен. Несмотря на то что "все изменения" в данных будут видны их нельзя менять/читать одновременно из разных потоков. Может вы спутали пример с двойным буффером когда происходит переключения через атомик поинтер между тем в который пишем и тем из которого читаем, тогда бы это имело смысл, но строго для 2 потоков.А ещё можно поступить точно так же, но проще - совершенно произвольно запретить на код ревью поднимать темы код стиля и сначало мягко объяснить нарушителем запрета, второй раз жёстко высушить и что то там ещё, а третий последний.
И внезапно люди научаются жить без линтеров, читать код в любом стиле и писать так как душе нравится. Оставить можно только совсем базовые принципы именования и то сделать упор, но то как не надо именовать, но не навязывать жёстко как надо.
Консистентнгсть это миф, у вас в коде всегда смесь, ваш код, стандартная библиотека, фрэймворк, и поверх ещё чужие библиотеки и каждый в своем стиле и нужно часто все это в одном месте/функции. И как то все живут и не жужат, а тут видители колега совсем берега потерял в моей песочнице ссыт не по-моему уставу.
Ну можно и так сказать, но есть более общеупотребительное слово, вы сразу поймете о чем речь если типом х и у будет строка. Я просто взял простой и понятный код и переписал на рэнджи. Потом для проверка попросил кита подумать и объяснить что делает код, умный гад, думал долго, но ответил правильно, но что ещё важнее он показал, что моя прямая попытка смапать на рэнджи работает не совсем так как оригинальный код. В оригинале find_first_not_of, что не тоже самое что и в примере выше. Работает правильно если у содержит 1 элемент, но в оригинале у меня стандартный набор элементов для этого алгоритма в качестве дефолта идет. А написать на рэнджах правильно низя т.к. нету там find_first_not_of. Не подвезли даже в с++26. Можно конечно извернуться и написать через find_if_not + contains/any_of или find_first_if + none_of, но и так уже сложно читать.
Очень интересно, а почему вы так думаете и чем пользуйтесь когда вам надо с классами или указателями работать?
Так давайте проверим, алгоритмы говорите, читабельные говорите и все такое блабоабла.
Назвались груздем полезайте в кузовок. Рэнджи ещё более самые супер пупер лучшие алгоритмы, авто везде не просто так, а что бы алгоритм был максимально дженерик и компилятор/рэнджестроители могли показать максимальную оптимизацию под конкретно ваш случай. Там конечно можно ещё концептов на х, у навесить для пущей пидидитости, но это только добавит шума и не облегчит ответ на вопрос. Что делает эта функция одним словом? Я специально заменил нормальные имена на х, у ибо тогда станет очевидно.
Гусары не читерить, ллмы трёх метровой палкой не трогать. В идеале сипипиреф тоже не открывать если вы за алгоритмы должны и так понять.
Вопрос со звёздочкой насколько производителен такой код? Годен для геймдева?
Так хорошо, а что вы ожидали? Точнее все работает в соответствии со спекой https://en.cppreference.com/w/cpp/container/vector/erase Мне реально интересно какие у вас были ожидания от работы этого метода до того как вы разобрались с вопросом? Второй вопрос вызывающий интерес, когда вы разобрались как это работает почему вы решили написать об этом статью?
Мне кажется, несмотря на то, что вы разобрались как работает ирэйз вам все ещё не понятно почему спека на него именно такая (ну просто какие то деды решили, что так им удобней 100500 лет назад), а не так как вы ожидали. Я могу помочь вам разобраться почему спека именно такая, а не как вы ожидали.
К моему счастью, русский действительно не пригодился. Тот же МФТИ из статьи предлагает зачёт/не зачёт ну чтобы удостовериться, что абитуриент вообще понимает русский и может изъясняться на нем. А вот физика пригождается чуть ли не каждый день, но не по работе, а по жизни. Конкретный раздел - электричество, ну то которое совсем базовое - электротехника, закон ома вот это все. Механика изредка - в общем как раз школьный курс.
Все число дробилки которые я кодил или видел вообще не требует динамической аллокации, если точнее, то она конечно нужна т.к. размер стэка ресурс ограниченный. Все ж таки буфера алоциртся в хипе, но 1 раз перед началом расчетов. Поэтому фиолетово сколько у вас там потоков. Я не видел успешных число дробилок которые чё то динамически аллоцируют посреди рассчетов в таких количествах когда нужно думать об аллокаторах.
Динамическая аллокация жизненно необходима в событийных системах, но если нет жёстких требований по лэтенси то и стандартного аллокатора достаточно. А когда лэтенси важно то первым делом аллокации вообще выпиливают и только когда от них нельзя или дорого избавиться начинают думать над аллокатором.
В далёком 2006 мне надо было портировать очередную жей2эме игру на платформу где использовался с++. Все контора этим занималась - пост продакшн на мобилках тех времён. Не помню точно какая возможно это был Соник. Так вот на большинстве телефонов все работало норм, но была платформа где было медленно. Я залогировал (построил гистограмму) всех аллокаций, ну к моему счастью 95% были блоки на 12 байт. Ничего не зная про все эти типы аллокаторов я просто совместил блочный и фри лист, додуматься до этого не много ума надо. Метаданные (связный список свободных блоков) был размещен в самих блоках одинакового размера. Я сделал список на массиве и по сути указатель на следующий блок это индекс в массиве. Т.е. был большой массив блоков по 12 байт, когда блоки свободны они хранили индекс следующего блока, а когда заняты какие-то данные.
Померял сколько нужно блоков, ну как померял увеличивал размер пула по фибоначи пока не перестало крашится потом увеличил ещё разок на всякий случай и успокоился. Игра стала летать. Т.к. я заранее сделал размер пула точно больше чем нужно блоков, то даже выкинул проверку на нет блоков.
С тех пор никогда больше мне не требовалось заниматься подобной магией, кроме трэйдинга по причине лоу лэтенси требований. Так вот все эти аллокаторы нужны либо в играх либо в трэйдинге, звук иногда, но там можно просто все заранее преаллоцировать. Короче в обычной жизни даже стандартного аллокатора хватает, не говоря о том что есть джейемалок если обычный не устраивает.
Большинство проблем надумано зелёной повесткой. Суммы ежегодных потерь вообще не имеют смысла и практически одной природы с недополученной прибылью, с той лишь разницей что "потрачены". Потери не является чем то объективно необходимым, а ограничены сверху лишь беджетом, а с низу жадностью зеленых. Но не все конечно.
Реальная проблема это кролики и прочие вредители. Что такое вредитель в этом контексте? Не тот кого называют зелёные вредителями, а тот кто реально мешает ЛЮДЯМ. Зелёные во вредители записывают вообще всех не эндемиков (включая самих людей хехе, но не оч любят об этом говорить и афишировать).
Планете/природе вообще фиолетово кто и каким образом куда попал, не смог приспособиться - ну сдохни че, свято место пусто не бывает. А зелёные это настоящие вредители, мало того, что они тратят любое количество денег на безуспешное решение "проблем" и само собой хотят ещё больше в следующем году, ну так как в этом не получилось и надо просто больше ну и зациклить эту схему. Так они ещё и закрывают доступ к рэнджам для туризма, т.е. люди с налогов которых все это шоу устраиваются не могут пойти и посмотреть на этих сраных недобидытых бедненьких эндэмиков.
Это очень удобно и повышает прозрачность работы зеленых, ну чё победили Х в этом году - ну не совсем, ну ладно, а чё там с У которых мы и защищаем уничтожением Х? Стало лучше, хорошо, а посмотреть можно - низя или нахер, глупых вопросов почему нельзя не задавай и вообще дай ещё денег. Вот так выглядит деятельность зелёных для меня. Я из НЗ здесь практически такой же дибилизм.
Потравили кроликов, ёжиков, и котов в городских парках/местах для прогулок (там где они вот вообще никому не мешают) ради сраных птичек. С собаками гулять нельзя почти везде, кроме пляжей и то не всех и некоторых специально отведенных мест. Каури (деревяшечка такая, красивая большая) тут спасают уже десятки лет от грибка, и вот по этому поводу запрещено гулять почти по всем рэнджам где оно растёт.
С поссумами вообще прикол вышел, они объявлены пестом ибо инвазивные и все такое якобы воедят птицам т.к. едят яйца. Завезены из дружественной Австралии для борьбы с кроликами - шизофрения во всей красе. Там то они не инвазивные и защищаются, а тут отстреливаются. Но да ладно, ёлки-палки которые сосны тоже объявлены пестом, т.к. быстро растут и мешают местной флоре. Так вот цимес, недавно выяснилось, что поссумы жрут шишки и борются с ёлками как теперь быть со статусом поссумов не знают то ли все ещё пест то ли уже не пест.
Мораль сей сказки проста, завезли и завезли не такая уж и проблема, ЭКО система сама придет в равновесие возможно не скоро, но придет. Решать надо (тратить деньги) не на то что бы убивать одних во имя других (они сами разберутся кому жить, а кому нет), а на решение проблем которые мешают ЛЮДЯМ. Главное во всем этом люди, а не пресловутое представление зелёных о том как правильно, а как нет.
Бесплатный демо доступ на 15 минут и автодозвон чтобы таких же демо халявщиков обгонять, а через месяц звездюли от родителей за счёт на превышение минут на месяц. Потом тоже самое, но не более раза в день, что бы лимиты не нарушить.
У меня был скачан мсдн и все нужные книги в оцифрованной версии, а самые нужные - Страуструп - в бумаге.
Ну например вы реализуете сэтабл синглтон. В продакшеге у вас один код который его сетит и он всегда исполняется при инициализации, а в тестах вы резетете его после/перед каждым тестом. Да конечно можно и функцию резет в самом типе реализовать, но она не нужна в продакшнене, а опшионал ее и так реализует.
Я как раз на плюсах и пишу там помимо * и -> есть еще и валью и валью_ор и в 23 ещё и прочие функциональные зены и элсы подвезли. Так что все там есть чтобы писать без уб. Но уб наше все конечно куда ж без него. Я чиню говнокод и на плюсах (прод) и на питоне (авто тесты) и в ява скрипте (кумл/гуй). Конечно плюсы 99% моего времени, но я не заметил каких то принципиальных отличий ну опять же кроме самого важного для плюсов - весь спектр уб. Ну т.е. да на плюсах гавнокода я вижу сильно больше, но он это интересней что ли.
А с проверкой один раз в мэйне может не получится опять же если поодакшен по бизнес логике требует опшионал, а если не требует то и проверять явно ничего не надо, а вместо этого использовать функции/апи без уб.
Ну почему же так радикально? Например опшионал может быть нужен только для тестов, а не в продакшене, тогда нет нужды ни в каких проверках, а если все таки вдруг кто то что поломал в продакшене и синглтон пуст при первом использовании то доступ к значению опшионала кинет исключение или терминирует программу кому как нравится.
Если же опшионал на самом деле нужен в продакшнене то ваша замена с конструктором не эквивалентна т.к. проверку на пусто кто то где то всё ж таки должен делать.
В поддержку предыдущего оратора и чтобы было чуть более понятно на примере. Квадрат прекрасно сабклассирует прямоугольник если интерфейс прямоугольника не содержит инплэйс мутаторов.
Тогда не составит труда корректно с точки зрения лсп реализовать перегрузку в сабклассе квадрат. При этом квадрат может иметь свои специфичные методы которые возвращают квадрат, что бы можно было и дальше сабклассировать при необходимости.
Тут конечно может возникнуть оверхед на то чтобы боксить возвращаемые значения в зависимости от языка и вашей реализации.
Но тут главное какую задачу решаем, если это векторный редактор и вы мышкой тянете сторону квадрата, то наверное вы хотите чтобы он квадратом и остался и тогда можно делать мутабельную версию которая при изменении длины и ширину поменяет, а вот версия выше юзеру не понравится т.к. квадрат мгновенно превратится в прямоугольник. Просто в мутабельной версии вы должны каким то образом выразить (хоть в документации) что изменение длины не подразумевает неизменность ширины и тогда нет никаких проблем с лсп и в мутабельной версии. Можно даже оба подхода совместить и иметь визЛенч и сэтЛенч.
Ответ очевиден, синглтон лучше тем, что не требует передачи контекста/себя. Вот вы сосласиь на DI, а разве инжекция не требует того самого ну этого как же его, а вот синглтона?
Есть способы обойти ВСЕ перечисленные проблемы и остаться синглтоном, ну собственно DI это и подтверждает, но можно и самому сделать если надо.
Вот когда появится потребность мульти ботов или сикуреэс, вот тогда и перепишем с синглтона на 2(М) синглтонов просто разного типа. А с тестами все не просто, а элементарно - сделайте уже наконец функцию резет вашему синглтону или ещё лучше реализуейте сэтабл синглтон и тогда вот это поворот можно даже хоть мокать хоть фэйкать его как угодно.
А синглтонов в коде полно, например ОС апи - синглтон хоть и явно никакого объекта не требует, логирование, стандартные консольные потоки ввода/вывода, ФС, реестр и т.д.
Синглтон надо уметь готовить, а не критиковать. Если чего то стадо действительно больше одного ну просто уйдете от синглтона позже, да может быть тяжело и больно, но не ужас ужас ужас как пытается об этом сказать автор.
Это зависит от того как вы сделаете. Вот вы тут критикует курлу говоря, что там асинхронность с боку, но там как раз сделано так что вы сами управляете пулом потоков. Там очередь, а на чем ее крутить решает юзер код. Точно также можно сделать таски обработки запросов, а в апи выставляется функция запуска очереди. В простых случаях эта функция вызывается на одном потоке, хотите в главном как у вас в примере хотите в отдельном. В сложных случаях вызывается несколько раз из нескольких потоков - масштабирование.
Какие задачи решает курл я вроде бы как знаю, и меня удивило, что по вашему мнению он не покрывает хттп2 транспорт. Расскажите какие задачи решает ваша хттп2 реализация которые не решаются курлой? Какой такой гибкости вам не хватает?
Да и обычный фетч контен можно сделать без скачивания только это все костыли плюс брать что то из кеша возможно при соблюдении правил - сипиэм должен быть последним и предыдущий подход должен юзать фаинд пэкедж. Ну для буста это скорее исключение если кто то не через фаинд его подключает, а вот много других либ далеко не всегда предоставляют симэйк скрипт и там уже может не получиться у сипиэма найти что то в кешах. В общем мне кажется, что вы рано считаете, что основная проблема с++ решена для вашей либы. Если вдруг у вас будет какое то количество сторонних использований и никто не будет жаловаться тогда да решена.
Я не очень понимаю, что вы хотите этим сказать. Вы же не утверждаете, что до с++ 20 на этом языке невозможно было реализовать асинхронность? Понятие лучший тоже никак не раскрыто, а если вы на самом деле считаете, что корутины это единственный способ, то качественная оценка лучший не имеет смысла. Это как первый элемент в очереди из одного элемента он же и последний - худший.
Я хочу заменить вашу хттп2 + азию на курлу или культю не меняя код апи.
Если вы про SAX парсер то например nlohmann::json умеет такое.
Там сложно объяснить простым комментом поэтому я не буду вдаваться в подробности. Есть ещё одна альтернатива вашей архитектуре, можно парсить хтмл от телеги и генерить какой нибудь стандартный рест апи файл, а уже потом используя стандартные генераторы реста получить готовую либу не только на с++, но и для других языков. Мы например так генерим с++ транспорт культевый для своих рестов, где то мне попадались генераторы и на другие реализации сети. Очевидно эта работа (по предоставлению стандартного реста) должна быть сделана самой телегой, но раз они не сделали то это было бы наиболее полезно.
Есть разница между разбивкой библиотеки на части/фичи и отделение каждой части в независимую библиотеку. Разбивка на библиотеки сложнее, но как вы говорите гибче. Когда у вас разбивка идёт на фичи, то сборка/зависимости управляются единообразно в родной либе, а когда разбивка на либы, то необходимо предоставить интерфейсы к зависимостям на уровне сборки в каждой либо - больше работы/сложнее, но позволяет легче интегрировать только необходимые части в существующие проекты.
Я пишу с телефона и это очень больно, дальше идут параграфы не совсем согласованные между собой так как написаны они были в разном порядке, а это вступление вообще самым последним, чтобы хоть как-то смягчить удивление от моего коммента.
Скажите, а чем не устраивает классический вариант когда из главного потока синхронно в цикле полим и запускаем синхронную джобу на пуле потоков которая занимается обработкой?
Насчёт хттп2, чем вас курла не устроила?
На буст у многих аллергия по причине монструозности и отвратительной документации. Имхо делать его зависимостью в либе это вообще самое последнее средство когда по-другому вообще никак. Т.е. для меня это сразу красный флаг и четкое нет вашей либе, но я понимаю что художник вы и вам так красиво.
Вот например у нас в проекте тоже есть буст и если добавить вашу библиотеку то потенциально может появиться конфликт версий буста на ровном месте, потому что мы обновляем его только когда приспичит. И зачем нам этот головняк с разными версиями буста, я понимаю, что скорее всего никаких проблем не будет, но все же?
Если я правильно понял то у вас код пляшет от с++ структур по ним генерится сериализация в жисон, но есть и другой путь, вы можете генерить жисон, а потом из него генерить с++ структуры. Не уверен, что это не мое личное определение/понимание, но я называю этот подход обратным орм. Имхо сильно проще чем обычный орм когда источником правды служит конечный язык, а не скул/жисон. В идеале вам вообще не нужна билд зависимость от жисон библиотеки, вместо этого можно сгенерировать прям код сериализации только для ваших структур используя жисон библиотеку как дев зависимость в терминах раста, но честно я не знаю насколько это осуществимо на плюсах сегодня.
Имхо только так и надо. Вот например у нас используется йокто, а тамошние художники решили, что ходить в сеть во время сборки это вредно для здоровья. И все эти ваши фетч контенты с сипиэмами не работают, надо костыли делать. Опять же в экосистеме раста этот вопрос решен красиво, библиотека бьётся на более мелкие, т.е. например есть только та что генерит ц++ апи который про жисоны ни сном ни духом не знает, а просто отдает пэйлоад строкой , поверх уже сериализация в структуры и роутинг на команды, где то ещё будет подсос зависимостей из сипиэма в виде отдельной либы. А на границах интерфейсы. Зачем? Ну у нас и культя в проекте тоже есть и у нее тоже на любой вопрос свое решение и жисоны и сеть асинхронная имеются. В идеале я бы мог взять например ваш генератор апи и подставить свой транспорт потом распарсить жисон своей либой уже в свои структуры. Да это все сильно сложнее чем то что у вас, но зато намного проще комбится с существующими проектами. Ваша библиотека для написания бота отдельным приложением с ноля, а в существующий проект так просто как хочется не воткнется.
Корутины конечно модно и все такое, но ведь курла такая же асинхронная (как и культя), а если есть (а иначе нафига этот бот нужен) тяжёлая обработка то без пула потоков с джобами все равно не обойтись. Т.е. ваш демо/эхо бот точно также можно сделать с курлой в один поток, а что не демо так нужен пул все равно, так и зачем тогда эти корутины конкретно в этой либе? Я могу понять выбор корутин как достаточно универсальный интерфейс для транспорта, но вы транспорт гвоздями прибили и заменить его нельзя, тогда зачем корутины?
Я не критикую, а хочу понять вашу мотивацию/цели/проблемы связанные с выбором именно такого дизайна библиотеки. Т.е. мне лично код примеров вообще не интересен был как и сама либа, а вот как вы принимали архитектурные решение было бы интересно почитать.
Мне кажется, что не существует бизнес проблем которые формулируются как
Бизнес проблемы они больше про - стало больше пользователей чем раньше и система не тянет по производительности. Наши инженеры посмотрели и сказали что модуль Б не вывозит и его надо заменить на модуль Ц. Или наши заморские партнёры по доброте душевной больше не берут наши тугрики и надо заменить модуль Б на модуль Ц. Или наше отечественное руководство заботится о нашем бизнесе и наших пользователях и настоятельно просит использовать модуль Ц из белого списка вместо модуля Б. Или модуль Б был написан ещё древними греками по заветам самого Зевса, но последний сервер способный исполнять этот код запланирован в утиль и надо заменить на модуль Ц который может работать на наших серверах.
Бизнес проблема звучит так, что не возникает вопросов зачем мы хотим заменить Б на Ц, а вот инженерная задача не отвечает на вопрос зачем. Я не буду никого обманывать и сознаюсь что решать бизнес проблемы мне не интересно, а инженерные задачи интересно, но все же разница есть.
В любой из этих историй просто замена модуля Б на модуль Ц даже если он скрыт за абстракцией это утопия. Может ли помочь абстракция - да может, но может и наоборот немного помешать. Скорее всего абстракция больше поможет (немного) чем помешает, но будет мешать всю свою жизнь особенно если бизнес задача не возникнет. Т.е. платить за абстракцию мы будем всегда, а воспользоваться может и не удастся.
Если ваше бизнес решение с лёгкостью позволяет заменить базу данных на другую, то вероятно вам база данных в общем то избыточна и можно обойтись более простыми == дешёвыми средствами. Если транспорт можно с лёгкостью заменить на другой то опять же можно обойтись чем то более простым.
Мой поинт в том, что такое может быть, но я больше ожидаю такое от стартапа где эффективность не является конкурентным преимуществом и реализации скрытые за абстракцией можно менять просто, но я думаю и без абстракции их тоже можно заменить не сильно дороже потому что это стартап и/или эффективность не главное, но дороже да. Там где эффективность реализации это конкурентное преимущество я очень сильно не ожидаю таких чудес как просто замени Б на Ц и все готово я такого не встречал.
Это не значит что ДИП не нужен никогда это значит, что он нужен ИМХО только тогда когда для решения бизнес задачи вам надо иметь более одной реализации т.е. вам нужно использовать и модуль Б и модуль Ц вот тогда и нужно внедрять эти абстракции. Да я знаю есть ещё юнит тесты опять же ИМХО для бизнеса нужны не они, а функциональные тесты которым наличие абстракций ни как не помогает. Я сторонник фэйкания внешних зависимостей вместо мокания внутренних реализаций. Юнит тесты имхо идеальны для библиотек решающих конкретную инженерную проблему, а для бизнес логики/приложений предпочтительнее тесты функциональные.
Да конечно это все философия, стилистика, субъективная вкусовщина, но ведь статья про солид, а что это если не философия?
ПС если у вас 2 модуля рекурсивно зависят друг от друга то их разделение через 3 модуль не всегда то что нужно. Возможно их объединение в один модуль будет иметь больше практического смысла чем разделение любой ценой ради соблюдения каких то других философских принципов.
Я понимаю что разделение, навязывание структуры, введение ограничений предназначено для уменьшения энтропии системы, но это все имеет цену - когнитивную цену. Мой опыт говорит мне, что люди в целом любят рассуждать о красивых системах, но на практике те же самые люди принимают очень сабоптимальные решения, потому что командные цели, скрам, объективная когнетивная сложность красивых решений и не уверенность в своих способностях / страх облажаться давят сильнее чем чувство прекрасного. Лично я нахожу вкус и запах легаси спагетти кода вполне себе съедобным, и не очень люблю изысканную пишу гурманов. Мне главное, что бы дёшево и нажористо, а утонченные вкусы и эстетическая красота за дорого не очень привлекает, хотя на выходных пойдет для разнообразия.