четверг, 2 февраля 2023 г.

[prog.c++.flame] Бомбануло у меня от копипасты сегодня

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

Ниже тоже неплохо. Три почти одинаковых фрагмента, отличающиеся всего одной строчкой в середине. Но тут хотя бы понять можно почему именно так: может мы ограничены C++11 и нет возможности использовать обобщенные лямбды, да и фрагменты коротенькие, типа не так засоряют восприятие.

Однако, для меня лично все равно это попахивает известной субстанцией. Слишком уж много лишних деталей вываливается на пользователя, да и не сложно уже существующий код видоизменить так, чтобы не приходилось вручную звать close() для открытых std::ifstream. Хотя я бы все равно сделал бы что-то вот такое, если бы пришлось оставаться в рамках C++11:

template<typename Setter>
void trySetBookmarksFromFile(const char * fileName, Setter && setter)
{
   std::ifstream docFile(fileName, std::ios::in);
   if(docFile) {
      std::stringstream strStream;
      strStream << docFile.rdbuf();
      setter(strStream.str());
   }
}

trySetBookmarksFromFile("bookmarks_1.conf",
      [](const std::string & v) {
         ImGuiFileDialog::Instance()->DeserializeBookmarks(v);
      });

trySetBookmarksFromFile("bookmarks_2.conf",
      [&fileDialog2](const std::string & v) {
         fileDialog2.DeserializeBookmarks(v);
      });

trySetBookmarksFromFile("bookmarks_c.conf",
      [&cfileDialog](const std::string & v) {
         IGFD_DeserializeBookmarks(cfileDialog, v.c_str());
      });

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

В общем, не делайте так.

6 комментариев:

Stanislav Mischenko комментирует...

По моему опыту приведённые примеры копипасты это такой типичный пример "ковбой кодинга" повсеместно встречающийся у американцев. Нашим программистам более свойственно сидеть и доводить код до идеального состояния. Опять же я не жил в Америке, но довольно плотно общался с американцами, которые приежали к нам. И вот по моим наблюдениям, когда у тебя писать код это не вид искусства, а, без приувеличения, способ выжить, ибо живёшь ты в кредит, то пишешь код ты именно на скорость. И если копипаста для тебя это самый быстрый способ, то будет копипаста.

eao197 комментирует...

Мне думается, что все это следы "инженерной культуры". Кому-то ее привили во время обучения, кому-то нет. Полагаю, что в Штатах производство программистов было поставлено на куда больший поток, чем у нас. Посему этой самой культуры не всех не хватило.

Stanislav Mischenko комментирует...

Нет, дело не в культуре. Дело именно в деньгах. Время это деньги, код - нет. Когда я расспрашивал американцев, то выяснилось, что они прекрасно знают, что такое красивый код, что значит "code smells" и т.п., но на этом не заработаешь, если конечно ты не зарабатываешь, например, на книгах и статьях. Они часто пишут код на выброс, если что-то не работает, то просто пишут заново, если там конечно ни какой-нибудь "rocket science", и это можно переписать за weekend. Помню как-то видел комментарий от нашего программиста по поводу кода виртуальной машины C#, мол вы видели, там весь сборщик мусора написан в одной функции, какой кошмар. У меня это вызвало только улыбку, ибо это полное непонимание, как эти люди работают. Заработать на этом коде можно было только, если там есть какие-то патенты, на какой-нибудь хитрый алгоритм. И так как код писался в конце 90-х, патенты, скорее всего, были, ибо тогда много чего изобреталось впервые. Как только срок патентов истёк, код перестал нести какой-то ценности и был выложен в публичный доступ. Сам по себе код никакой ценности не имеет и поэтому может быть написан как угодно, главное быстро.
Вообще хочу заметить, что так как американцы не трясутся за свой код, работать с ними намного приятние. Самые токсичные это русские конторы, там не дай бог ты напишешь код просто не так как бы хотелось местным авторитетам, будет целый спектакль с разгромом твоего кода. В тоже время для американцев, как правило, существует только два вида кода, тот, который работает и тот, который нет.

eao197 комментирует...

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

Знаю только по себе, что хороший код (в том числе и без копипасты) обходится дешевле даже в краткосрочной перспективе. Не говоря уже про долгую.

sv комментирует...

Не любой дублирующийся код плохо. Например, что если нам на вход поступают json-ы от двух разных компаний, и мы должны их уметь обрабатывать. При этом, эти json-ы на 95% между собой совпадают, но на 5% всеже нет. И вот что тут делать, придумывать различные паттерны, шаблоны, лямбды, тд и тп или просто скопировать один и тотже код 2 раза? (А иногда даже сильно больше, чем 2 раза).

Другой пример, работал однажды в одной игровой студии. Эта студия выпускала абсолютно одинаковые игры под разными обертками. И над каждой такой игрой работала отдельная команда. И раз в какойто период времени к каждой команде подходил менеджер и говорил "хочу такую фичу" (абсолютно одинаковую). И каждая команда пилила абсолютно одну и туже фичу, в своем стиле конечно. Поначалу я тоже сильно бомбил от такого подхода, но потом начал понимать преимущества.
Во-первых, почему бы и нет, если деньги у компании есть. Во-вторых, возможно развивается какая-то конкуренция, и можно какието интересные наработки утащить из другой команды. В-третьих, бас-фактор, что если одну команду целиком собьет автобус. В четвертых, как вообще себе представить процесс, при котором код не будет дублироваться. Типа, какая-то одна выделенная команда пишет данную фичу, а остальные 4 ее ждут? И какова вероятность, что чтото пойдет не так? (подсказка, почти 100%). А в данном случае, даже если одна из команд облажается, то по крайней мере остальные 3 - нет. И т.д.

Так что не сказал бы, что дублирование кода это обязательно плохо

eao197 комментирует...

@sv

> Например, что если нам на вход поступают json-ы от двух разных компаний, и мы должны их уметь обрабатывать.

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

> Поначалу я тоже сильно бомбил от такого подхода, но потом начал понимать преимущества.

Если это разные команды, которые работают над разными кодовыми базами (и эти базы затем не сливаются в одну общую), то не вижу никаких проблем.