четверг, 25 апреля 2024 г.

[prog;work;wow] Марко Арена завершил свою серию статей про SObjectizer

Марко Арена сегодня завершил свою серию статей "SObjectizer Tales", начатую в октябре прошлого года. Полный список статей из этой серии я приведу ниже.

Сперва же хочется сказать слова благодарности. Результат получился впечатляющим, я такого не ожидал от слова совсем. Вышло очень и очень круто, большое спасибо, Марко!

Так же поделюсь своим впечатлением от произошедшего. И тут сложно подобрать слова. Наверное, самым точным цензурным вариантом будет -- я шокирован. В хорошем смысле этого слова.

Изначально я даже и не мог предположить, во что же это все выльется. Когда Марко спросил у меня как я отношусь к идее того, что он сделает серию постов про SObjectizer, и в самых смелых фантазиях невозможно было представить, что эта серия будет содержать тридцать (тридцать, Карл!) статей.

Как по мне, так Марко написал целую книгу. Что по объему, что по глубине и качеству материала.

И, что особенно радует, так это то, что написано все это не кем-то из SObjectizer Team, а пользователем SObjectizer-а. Скажи мне об этом кто-то еще года два-три назад, я бы счел подобное ненаучной фантастикой. А теперь это реальность.

Более того, я бы даже назвал выход серии "SObjectizer Tales" целой вехой в истории развития SObjectizer-а. Важной и значимой лично для меня.

Так что, да, я шокирован. В хорошем смысле этого слова.


Вот как в итоге выглядит вся серия.


PS. Что доставляет отдельно, так это слоган, который Марко выбрал для своей серии: Concurrent C++, made simple. Таки да, для этого все когда-то и затевалось. Но я бы насколько лаконично и емко выразить бы не смог.

понедельник, 22 апреля 2024 г.

[prog.c++] Вредных советов пост: пара-тройка способов усложнить жизнь тем, кто будет сопровождать код после вас

Хочу поделиться многолетним опытом. Работает на 100%, а иногда и на все 146%. Так смело можете брать на вооружение, если решили конкретно поднасрать своим коллегам.

Во-первых, используйте std::pair и std::tuple для долгоживущих объектов. Особенно если эти объекты свободно перемещаются между различными частями программы.

Поверьте, настоящие программисты (тм) всегда будут точно знать, что означают it->first или std::get<3>(*it).

Наверняка на вашем пути встретятся душнилы, которые будут утверждать, что std::pair и std::tuple нужно ограничивать очень маленьким скоупом. Вроде возвращаемого значения лямбда-функции или же обычной вспомогательной функции, но которая вызывается всего в одном-двух местах. А для всего остального нужно создавать нормальные структуры с названиями полей, соответствующими предметной области.

Не обращайте на них внимания. Это же склеротики, которые не могут удержать в памяти даже два простых названия -- first и second, хотя что может быть проще? Ну и наверняка им платят за строчки кода, а не за решение проблем. Вот они и фигачат по 100500 строк там, где можно обойтись одним std::pair-ом.

Во-вторых, забудьте такую вещь, как strong typedef. Тем более, что в C++ из коробки ее и нет. Так что это вообще не ваш путь, а те, кто про пытается заикаться о strong typedef, просто учились программировать на Pascal-е, а значит старпёры и ничего не понимают в современной разработке софта.

Если у нас есть строковое имя пользователя и строковый же пароль в виде открытого текста, то достаточно простого std::string.

Вводить какие-то новые типы UserName и PlainTextPassword? Ради чего? Ради того, чтобы случайно не пихнуть пароль туда, где ожидается имя пользователя?

Да это вообще смешно. Ведь так никто не делает. А если вдруг, так это от кривизны рук. Настоящие программисты (тм) таких ошибок не допускают.

Но даже если какой-то джуниор-разработчик такую ошибку допустит, то он же сам себе злобный буратино, да и тестами все это ловится на раз-два.

Так что никаких strong typedef-ов. Забудьте как страшный сон.

Ну и в качестве бонуса: вам не нужны ни using, ни typedef. Если у вас есть map, значением которого будет vector из queue, то вот прямо так и нужно записывать. Никаких вспомогательных using-ов и typedef-ов!

Ну а самые прозорливые читатели могли догадаться, что все эти советы легко комбинируются. Ведь это так просто:

void process_appropriate_items(
      const std::vector<
            std::pair<
                  std::pair<intint>,
                  std::tuple<std::string, std::string, std::string, std::string> > > & what)
{
   for(const auto & p : what)
      if(p.first.second > 0)
         process(std::get<3>(p.second));
}

Зачем выдумывать что-то еще? Неужели вам не понятно что означает p.first.second и std::get<3>(p.second)? Да ну, не может такого быть!


Перестрахуюсь на всякий случай: в каждой фразе здесь должен быть тег "сарказм". Иногда и не один.