LINUX.ORG.RU

Хороший код и говнокод

 , , ,


3

3

Привет.

Есть какой-нибудь крупный опенсорц-проект с хорошим кодом для образца? Питон или С++. Мне хотелось бы узнать.

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

Но опытный программист сразу распознает мой код как код новичка. Как на самом деле пишут опытные прогеры?

Можно еще накидать сюда примеры хорошего (эффективного) и плохого (неэффективного, дублирующегося и т.д.) кода.



Последнее исправление: RedEyedMan666 (всего исправлений: 1)

Ответ на: комментарий от RedEyedMan666

… , который можно изменить/поправить через много лет с меньшими усилиями.

Хороший алгоритм таким и является, а заумный - ЗАУМЕН.

Владимир

anonymous
()
Ответ на: комментарий от AntonI

Идеальный код скорее про Qt/Poco подход. В кратце - трейдоф в сторону упрощения поддержки. При этом, ни в коем разе не хочу сказать, что правила не применимы к более другому коду, просто в нём эти правила уходят на второй план за другими требованиями, но если код хорош, то solid, dry, kiss и т.п. читаются за нагромождениями того, что у многих авторов упоминается как фекалии. В общем читать стоит код, который пережил без масс рефакторингов хотя бы пару публичных релизов и при этом востребован.

Например я принимал участие в двух проектах практически на разных сторонах градиента:

  • ООД, чёткие интерфейсы, по спеке можно искать в коде и попадаешь почти слово в слово, притом спека сугубо не IT бизнес ориентированная, даже БА способны были по плюсовому коду быстро дать ответ как, и что происходит сейчас и даже что можно легко поменять.
  • Чёткие ОО интерфейсы наружу, страшный страх в потрохах: дырявые абстракции, дублирование кода под разные случаи, магические числа, непонятки от клиентов «что это за бредовая опция и почему после изменения её значения у меня всё стало в 50 раз медленнее?», прохождение через 5 стадий при чтении этого кода. К этому B2B коду помимо требований к портабельности и кроссплатформенности ставились жёсткие нефункциональные требования.

Оба эти проекта были одни из лучших в плане качества кода и поясню почему: к кодовой базе был применён единый набор соглашений разумных исходя из требований к системе. Если ты понял DSL - ты ориентируешься во всей кодовой базе, а не в отдельных участках. Всё остальное - наличие dsl, и разумность уровня его сложности.

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

Ты не умеешь объяснять. Ты всего лишь пончик. Где качественный код? Покажи мне его. Все эти твои умные реплики пользы не несут.

RedEyedMan666
() автор топика
Ответ на: комментарий от pon4ik

Ушел гуглить новые аббревиатуры и думать:-) Спасибо!

AntonI ★★★★
()

Но опытный программист сразу распознает мой код как код новичка. Как на самом деле пишут опытные прогеры?

Код - «ловкость рук».
Хорошая архитектура проекта бывает у хорошего «архитектора».

И это главное.

Владимир

anonymous
()

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

RedEyedMan666
() автор топика
Ответ на: комментарий от pon4ik

то лучше глянуть код Qt, QtCreator, GTest/Gmock и Poco

Когда доводилось пользоваться POCO, то время от времени требовалось заглядывать в их исходники и удивляться тому, как там все было примитивно, временами неэффективно и, местами, без заботы об exception safety. Остается надеяться, что стало сильно лучше за прошедшие годы.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Было просто? Так это самое главное преимущество такого кода. Чем проще(при соблюдении прочих требований), тем лучше.

pon4ik ★★★★★
()
Ответ на: комментарий от anonymous

Хорошая архитектура проекта бывает у хорошего «архитектора».

Если архитектура проекта плоха, то наверняка и «шаловливые руки» накуралесили чегой-то там.

Владимир

anonymous
()
Ответ на: комментарий от pon4ik

Было просто?

Было примитивно. Скорее тот случай, когда простота хуже воровства.

Так это самое главное преимущество такого кода. Чем проще(при соблюдении прочих требований), тем лучше.

По производительности, емнип, POCO всегда проигрывал. Как раз вследствии примитивности. Особенно врезалось в память активное использование std::string-ов внутри каких-то потрохов POCO в местах, где можно было бы обойтись локальным массивом char-ов на стеке фиксированного размера.

eao197 ★★★★★
()
Ответ на: комментарий от RedEyedMan666

не претендуя на полноту: у качественного есть свои особенности.

  1. соглашения об именах
  2. распроцедуривание.
  3. отсутствие устранимых тавтологий - то есть борьба с копипейстом
  4. вменяемые комменты, как минимум в местах, что могут вызвать затруднение в понимании при чтении другим разработчиком. код вообще-то надо писать не для себя, а для другого.
  5. функции небольшого размера, размер нормальной функции - от одной строки до нескольких десятков. все что больше должно иметь некое оправдание для существования.
  6. программа строится не из операторов и переменных, а из функций, объектов и вызовов методов.
  7. модульность
  8. сокрытие реализации по максимуму
  9. минимальная видимость в данном контексте того, что тут и видно не должно быть

ну и так далее.

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

alysnix ★★★
()
Ответ на: комментарий от lovesan

Хороший код и C++ это взаимоисключаемые параграфы.

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

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Есть такое прикольное слово-аббревиатура: POC. Уж не знаю, смотрели ли ли они его при названии либы, но на большее она и правда редко когда годится.

pon4ik ★★★★★
()
Ответ на: комментарий от lovesan

Т.е. ты здесь и сейчас готов указать на особо плохие места из этой реализации stl. Которые прямо нарушают какие-то конкретные критерии хорошего кода?

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

но на большее она и правда редко когда годится.

Так ведь как-то странно советовать как образец библиотеку, годящуюся разве что для POC.

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

eao197 ★★★★★
()
Ответ на: комментарий от lovesan

Такому напыщенному звездуну как вы странно не знать, что исходный код стандартной библиотеки C++ пишется специально в таком стиле. По целому ряду причин.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Я пытаюсь подвести ТС к мысли о субъективности понятий хорошо и плохо. Для POC - хорошо, когда примитивно но сокращает количество телодвижений для использования знакомых абстракций, а в идеале - сводит их использование к единому стилю(например работа с fs и https). Хороший код, это код который выполняет свою задачу сохраняя достаточный уровень простоты чтения и изменения.

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

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

И как раз для этих самых производительности/ресурсоемкости люди и вынуждены применять трюки, о которых затем приходится на конференциях рассказывать.

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

eao197 ★★★★★
()
Ответ на: комментарий от eao197

И как раз для этих самых производительности/ресурсоемкости люди и вынуждены применять трюки, о которых затем приходится на конференциях рассказывать.

пример такого характерного трюка приведите. на мой-то взгляд, трюкачество - первое дело, что может отправить код в мусорку.

alysnix ★★★
()
Ответ на: комментарий от alysnix

Наконец-то кто-то указал характеристику хорошего кода. «Хороший» – субъективное описание, под которым я имел виду нечто похожее на это.

  1. Reusable code (не дублирующийся)
RedEyedMan666
() автор топика
Ответ на: комментарий от RedEyedMan666

Наконец-то кто-то указал характеристику хорошего кода.

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

alysnix ★★★
()
Ответ на: комментарий от alysnix

программа строится не из операторов и переменных, а из функций, объектов и вызовов методов.

А объект в ООП разве не оператор и/или переменная? В остальном всё верно.

Функция становится методом как только помещается в класс. Технически это одно и то же.

RedEyedMan666
() автор топика
Ответ на: комментарий от eao197

Согласен, но, с но. Неоптимизированный код на Poco, при прочих равных окажется менее требовательным к ресурсам чем соответствующий неоптимизированный код на Java, в очень большом количестве типовых сценариев. А растёт это из всяких cow и nrvo, которые умудряются примитивности из poco иногда согнать почти в ноль и ты пользуешься posix и веб примерно на одном языке. Естественно, если ты понимаешь как правильно делать в posix.

Знаю случаи, когда i/o bound(!!!) код при старании двух очень квалифицированных команд давал разницу на порядок в лэйтенси не смотря на все старания по оптимизации с java стороны на одинаковом железе для c++ vs java, при этом плюсовый код был в состоянии «главное что бы хорошо читалось». И такое в принципе скорее тренд, чем нет при субмиллисекундных задержках.

pon4ik ★★★★★
()
Ответ на: комментарий от RedEyedMan666

В остальном всё верно.

О! Носитель вселенской истины! Я понял!

Ты ведь и так всё знаешь, а расспросить сюда пришёл, что бы посмеяться над недалёкими посетителями сего ресурса!

Поделись пожалуйста со мной крупицей своей мощи, дай вкусить мне этого священного знания!

pon4ik ★★★★★
()
Ответ на: комментарий от RedEyedMan666

программа строится не из операторов и переменных, а из функций, объектов и вызовов методов.

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

alysnix ★★★
()
Ответ на: комментарий от alysnix

пример такого характерного трюка приведите.

Например, вы используете библиотеку с богатой функциональностью и имеете возможность через type-traits просто выбросить из нее полностью то, что вам не нужно. Скажем, логирование. Или добавить в нее свое логирование без дополнительных прослоек в виде абстрактных классов с виртуальными методами.

Но а вообще люди на эти темы специальные доклады делают:

C++ трюки из Яндекс.Такси

Метапрограммирование: строим конечный автомат

на мой-то взгляд

На ваш взгляд никто и не посягает.

eao197 ★★★★★
()
Ответ на: комментарий от RedEyedMan666

Poco, EASTL(и всё что у них на GH есть), а также смотри чувака, по мне так это примеры хорошего кода особенно последний, т.к. так много по графике и движкам, как ты и просил, непосредственно игр подсказать не могу.

AKonia ★★
()
Ответ на: комментарий от eao197

Например, вы используете библиотеку с богатой функциональностью и имеете возможность через type-traits просто выбросить из нее полностью то, что вам не нужно.

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

alysnix ★★★
()

Кстати, отдельно хочу заметить - ни одного питониста сюда вообще не пришло. Ведь «этот код недостаточно pythonic» это универсальное замечание на ревью.

pon4ik ★★★★★
()

Создатель популярной инди игры UnderTale использовал в своем коде конструкции switch как минимум в 864 case. Его бы не приняли на работу никуда, но для него это сейчас не проблема, так как его игру купили миллионы людей и ему не нужно особо думать о работе.

https://ic.pics.livejournal.com/kvisaz/14814596/315950/315950_original.png

(Рандомный источник)


Для прикольной игры порой приходиться писать прикольный код. Это конечно не оправдание говнокоду, но если уж про игры говорить то первостепенно получить необходимый результат, а уже потом приводить его реализацию к чему-то там красивому ну или как минимум адекватному(читаемому) и то… =)

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от pon4ik

Ты ведь и так всё знаешь,

Та не, я ж всего лишь новичек-дурачок, нахватался глупостей из гугла. Сеньоры-помидоры знают тему лучше меня.

RedEyedMan666
() автор топика
Ответ на: комментарий от alysnix

Напиши helloworld без использования библиотек под современную ОСь, ну или хотя бы аппаратную платформу.

pon4ik ★★★★★
()
Ответ на: комментарий от alysnix

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

Но, опять же, если у вас от такого «трюкачества» идиосинкразия, то никто не заставляет вас идти на это «трюкачества».

Вы просто лишаете себя дополнительного мощного инструмента и все.

eao197 ★★★★★
()
Ответ на: комментарий от pon4ik

Я вашему слэнгу не обучен. Прошу извинить за непонимание.

RedEyedMan666
() автор топика
Ответ на: комментарий от alysnix

Покажи любому джависту CRTP, да ещё в комбинации с чем-то, он на твой код очень много различных отходов жизнедеятельности изольёт.

pon4ik ★★★★★
()
Ответ на: комментарий от alysnix

Я молчу про то, что автор достаточно толст что бы позавать в один тред тех у кого «явное лучше не явного» и тех у кого «zero cost abstraction».

pon4ik ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Для прикольной игры порой приходиться писать прикольный код.

А тут мне кто-то про недополученную прибыль рассказывал, бгг.

RedEyedMan666
() автор топика
Ответ на: комментарий от eao197

Типа как: каждый остаётся настолько высоко, насколько ему не даёт упасть его некомпетентность?

А как же всякие olap и озёра данных?

pon4ik ★★★★★
()

Для обсуждения /и не более/.

https://gist.github.com/bkaradzic/2e39896bc7d8c34e042b

Что я должен использовать?
C-like C ++ - хорошее начало, если код не требует большей сложности, не добавляйте ненужных C ++ сложностей. В общем случае код должен быть доступен для чтения любому, кто знаком с языком Си.
Не делайте этого , конец «обоснования дизайна» в православном C ++ должен быть сразу же после «Довольно простого, и его можно использовать. EOF ».
Не используйте исключения .
Обработка исключений является единственной функцией языка C ++, которая требует значительной поддержки со стороны сложной системы времени выполнения, и это единственная функция C ++, которая требует затрат времени выполнения, даже если вы ее не используете - иногда в качестве дополнительного скрытого кода при каждом строительстве объекта, уничтожении, и попробуйте заблокировать вход / выход, и всегда ограничивая возможности оптимизатора компилятора, часто весьма значительно. Тем не менее, спецификации исключений в C ++ не применяются во время компиляции, так что вы даже не узнаете, что не забыли обработать какой-то случай ошибки! И на стилистической ноте, стиль исключений при обработке ошибок не очень хорошо сочетается со стилем кодов возврата ошибок в стиле C, что вызывает настоящий раскол в стилях программирования, потому что большая часть кода C ++ должна неизменно вызывать нижележащие библиотеки C ,

Не используйте RTTI.
Не используйте C ++ во время выполнения обертку для C выполнения включает в себя ( <cstdio>, <cmath>и т.д.), использование C выполнения вместо ( <stdio.h>, <math.h>и т.д.)
Не используйте поток ( <iostream>, <stringstream>и т. Д.), Используйте вместо этого функции стиля printf.
Не используйте ничего из STL, которое выделяет память, если вы не заботитесь об управлении памятью.
Не используйте метапрограммирование чрезмерно для академической мастурбации. Используйте его в модерации, только там, где это необходимо, и там, где это уменьшает сложность кода.
С осторожностью относитесь к любым функциям, представленным в текущем стандарте C ++, в идеале ждите улучшения этих функций в следующей итерации стандарта. Пример constexprиз C ++ 11 стал пригодным для использования в C ++ 14 ( согласно куратору Джейсона Тернера cppbestpractices.com)

Владимир

anonymous
()
Ответ на: комментарий от anonymous

Могу изложить короче - не пишите ничего, пока не потребуется.

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

Типа как: каждый остаётся настолько высоко, насколько ему не даёт упасть его некомпетентность?

Код должен работать и делать то, что требуется. В случае C++, зачастую, производительность/ресурсоемкость входит в число требований.

Если код работает и требованиям удовлетворяет, то как именно он написан – это уже второй вопрос. А то и третий. А то и четвертый.

Другое дело, что если у разработчика большой арсенал, он может снизить собственные затраты на создание работающего кода.

Вот и все.

А как же всякие olap и озёра данных?

Не понял к чему это.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

При разработке собственного кода трюки могут очень сильно помочь в борьбе с дублированием кода, и с обеспечением надежности кода, и с получением производительного кода для случаев, которые в языке не очень-то и выражаются…

вам и карты в руки. язык С++. пример трюкачества, что очень «сильно помогло» вам или вашим коллегам. интересно будет рассмотреть это дело, на пример более «академического» решения. про конечный автомат даже смотреть не буду. последний конечный автомат я в коде видел… лет 15 назад. причем примененный явно не к месту.

alysnix ★★★
()
Ответ на: комментарий от eao197

Код должен работать и делать то, что требуется.

Дальше не читал, вы наняты.

pon4ik ★★★★★
()
Ответ на: комментарий от eao197

Не понял к чему это.

Случайно прочитал дальше. Это к тому, что на разных уровнях абстракции трюки будут разными и будут преследовать разные цели.

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

ни одного питониста сюда вообще не пришло.

Я пришел. Но я правда давно не считаю себя программистом.

Кстати, у меня давно сформировался такой объективный критерий - тот код лучше, который при прочих равных (читаемости и пр.) короче;-)

В частности я обычно ставлю несколько объединенных по смыслу операторов в строку - перевод строки тоже «знак препинания», а чем большую часть кода я вижу на экране единовременно тем проще работать.

В питоне иногда пробую несколько эквивалентных решений, и если не могу выбрать - выбираю то в котором меньше букв.

AntonI ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.