B>Код, который не может поддерживать обычный программер — это говонокод.
Угу, что обычный программер способен поддерживать код из книжки тов. Александреску?
B>- плохо документирован, или комментарии вообще вводят с толку B>- названия переменных/методов/классов не отражает сути B>- код неединообразно форматирован B>- нету автоматических тестов B>- роли классов не понятны B>- границы модулей/компонент размыты или вообще отсуствуют B>- отсутствие layers и вообще какой-нибудь разумной инкапсуляции. отовсюду все видно и доступно.
Однако, вот как бы комментарии в коде только мешают. Классы штука такая, абстрактная. Их может явно и не существовать. Имена могут быть и не на неком подобии anglijskogo. Автоматические тесты могут быть реализованы совершенно не в том виде. Границы без понимания творящегося в коде бывает не различить даже если они там предельно чётко очерчены. Форматирование же штука крайне скользкая, а декларативная инкапсуляция — вообще часто бессмысленна и только засоряет код.
То есть любой код не вписывающийся в рамки — говно. Ну да, мы же это уже вроде как выяснили? Вопрос — а судьи кто? Кто устанавливает рамки и почему все должны в эти рамки влезать. Как бы с сотрудниками одной конкретной компании всей понятно, у них всё это должно на уровне инструкций быть. Но у каждой компании, у каждого независимого проекта, у каждого индивидуала — рамки свои. Как результат суди все, и весь код говно. И к качеству кода эта характеристика обычно отношения не имеет.
B>Короче проблема качества кода реально существует. B>Игнорировать ее и даже высмеивать коллег, типа не умеющих читать код, — это не очень разумно
Дык, это же и есть главная проблема! Вот детей как бы сначала учат читать, а уже за тем писать. Программеров же почему то учат сразу писать, а читать не учат совсем, тогда как большую часть времени, по уму, программер именно читает код. Вот и получается что 'чукча не читатель — чукча писатель', всё вокруг говно и только чукча в белом.
RO>Если с самого начала хорошо спроектировать, затраты времени окупятся при первой же необходимости существенно изменить код. Тем более затрат-то: просто хорошо подумать, прежде чем шашкой махать, и не делать глупостей.
Дык не бывает в природе 'хорошо спроектировать', разве что в совсем вырожденных случаях. Обычно бывает — писать код эволюционно, от меньшего к большему, ровно то что нужно и не закрывая возможности развития. Фактически получается что махать шашкой в общем-то правильно, надо только это делать грамотно. Да, и глупости делать нужно обязательно, именно глупости дают опыт и новые возможности.
Здравствуйте, Alexéy Sudachén, Вы писали:
AS>Дык, это же и есть главная проблема! Вот детей как бы сначала учат читать, а уже за тем писать. Программеров же почему то учат сразу писать, а читать не учат совсем, тогда как большую часть времени, по уму, программер именно читает код. Вот и получается что 'чукча не читатель — чукча писатель', всё вокруг говно и только чукча в белом.
Фигню ты говоришь.
На длительных проектах с многочисленными релизами как раз больше приходится читать код, чем новый писать.
Я лично хорошо умею читать код и разбираться в нем. руку уже набил очень хорошо.
Был бы ты тут рядом, я бы тебе показал говнокод.
У меня есть возможность сравнить, как 3 команды делают по сути то же самое.
Размеры команд отличаются в разы.
Качество кода отличается разительно. В одной из команд, которая кстати самая большая, как раз говнокод.
Во всех отраслях нормально говорить о качестве.
С чего бы написание кода чем-то отличается от других?
То, что ты имеешь ввиду — это скорей всего безосновательное критиканство любого когда,
написанного другим. Такое тоже встречается. Особенно у молодых российских программеров.
Но это не означает, что проблема качества кода отсутствует.
AS>>Дык, это же и есть главная проблема! Вот детей как бы сначала учат читать, а уже за тем писать. Программеров же почему то учат сразу писать, а читать не учат совсем, тогда как большую часть времени, по уму, программер именно читает код. Вот и получается что 'чукча не читатель — чукча писатель', всё вокруг говно и только чукча в белом.
B>Фигню ты говоришь. B>На длительных проектах с многочисленными релизами как раз больше приходится читать код, чем новый писать. B>Я лично хорошо умею читать код и разбираться в нем. руку уже набил очень хорошо.
И что хотя бы половина людей в этих командах код тоже умеют читать? От чего же тогда такое плохое качество кода?
B>Был бы ты тут рядом, я бы тебе показал говнокод.
Не показал бы. Для меня такого понятия просто не существует. В любом коде есть недостатки, где-то их больше, где-то меньше. Где-то весь код один большой недостаток ) Короче, они есть всегда и более того, иногда могут превращаться в достоинства в зависимости от ситуации и наоборот. Надо просто принимать код как он есть, без эмоциональной окраски и проекций на собственные идеалы. А дальше уже решать что делать, если вообще что-то нужно с этим делать.
B>Во всех отраслях нормально говорить о качестве. B>С чего бы написание кода чем-то отличается от других? B>То, что ты имеешь ввиду — это скорей всего безосновательное критиканство любого когда,
Качество кода, в условиях заданных критериев — понятие объективное. Говнокод — характеристика субъективная по определению, и будучи использована превращает обсуждение любого кода в критиканство.
On 12.03.2013 13:33, Atik wrote:
> Все попытки "сначала хорошо спроектировать", которые я видел, > заканчивались жутким говнокодом. Потому что сначала у тебя просто нет > нужного понимания задачи и знания всех ее подводных камней.
Это естественно. Плюс еще требования меняются, мир меняется. Я тоже
много раз видел подобные попытки и все они заканчивались фиаско. Просто
с опытом приходит понимание, что не надо делать хорошо-идеально-плохо.
Нужно делать только то, что требуется и укладываться в требуемые сроки,
а код, архитектура — это баловство за счет работодателя.
Здравствуйте, Alexéy Sudachén, Вы писали:
RO>>Если с самого начала хорошо спроектировать, затраты времени окупятся при первой же необходимости существенно изменить код. Тем более затрат-то: просто хорошо подумать, прежде чем шашкой махать, и не делать глупостей.
AS>Дык не бывает в природе 'хорошо спроектировать', разве что в совсем вырожденных случаях. Обычно бывает — писать код эволюционно, от меньшего к большему, ровно то что нужно и не закрывая возможности развития.
Так последнее и есть основным признаком хорошего проектирования.
Вот тот же nginx. Они что, с самого начала не знали, что в конфигурационном файле будут использоваться $-переменные в директивах, и что юзеры могут захотеть использовать их в любых местах? Или что существует свыше 9000 всевозможных парсеров грамматик, которые намного проще адаптировать под изменяющиеся требования, чем велосипед? Например, они решили поддерживать нестандартный синтаксис с пробелами в URI — GET /bug/a horrible name with spaces.html HTTP/1.1\r\n... — но их парсер просто перебирает символы слева направо, и GET /bug/A Horrible Name With Spaces.html HTTP/1.1 ему уже не по силам, потому что после последовательности пробел-H он ждет T-T-P-slash.
http/ngx_http_parse.c — вообще очень занимательный файл. Там есть идентично объявленные макросы ngx_str3_cmp и ngx_str3Ocmp (причем это заглавная O, а не ноль), используются вот так:
и, при правильной endian-ности платформы, оптимизируют сравнение, кастуя 4 байта строки в uint32_t. А при неправильной, просто посимвольно сравнивают m[0], m[1], m[2] и m[3] — только ngx_str3_cmp не сравнивает m[3], а ngx_str3Ocmp — m[1]. Даже здесь есть логика — ngx_str3_cmp вызывается, проверяя строку на "GET " и "PUT ", а вызов ngx_str3Ocmp находится внутри if (m[1] == 'O') { проверить POST, COPY, MOVE, LOCK } else { проверить HEAD } — хотя и непонятно, какие копейки они выигрывают таким образом. Но если так делать, то почему не сравнить первые 4 байта запроса со строкой "GET " вообще до начала разбора, а не наткнувшись на пробел (после кучи невыровненных сравнений и условных переходов)? Почему не делать того же для строки "HTTP/1.1", пусть даже она не будет выровнена? Почему вообще вся эта черная магия делается вручную, а не есть результатом работы кодогенератора?
Кто считает, что этот подход не закрывает возможности развития, в того я первый брошу камень.
RO>Вот тот же nginx. Они что, с самого начала не знали, что в конфигурационном файле будут использоваться $-переменные в директивах, и что юзеры могут захотеть использовать их в любых местах? Или что существует свыше 9000 всевозможных парсеров грамматик, которые намного проще адаптировать под изменяющиеся требования,
На сколько я знаю историю проекта, то да не знали. И некто не полагал что этот проект вообще будет настолько популярным. Что опять же показывает что все эти мелочи значения не имеют.
Здравствуйте, Roman Odaisky, Вы писали:
RO>Здравствуйте, 11molniev, Вы писали:
1>>На мой взгляд код 7-zip и nginx хороший.
RO>Nginx — образец проблем, которые получаются, если делать всё вручную. Например, большинство директив в файле конфигурации не понимают переменные (нельзя сказать error_log /path/$some_var_depending_on_host/whatever.log) — казалось бы, должен быть некий централизованный механизм, но нет, парсер каждой директивы сам занимается разбором аргументов, причем полностью в ручном режиме, даже без грамматики. Я уверен, что приделать любую новую фичу к nginx — всё равно, что искать иголку в стоге заряженных граблей, нацеленных в ноги (или это не то сравнение?). Один if чего стоит, с миллионом подлых глюков.
1. Первоначально это был проект для личного использования.
2. Вы серьезно или издеваетесь? Парсер конфига это один из модулей. И их может быть несколько последовательно отрабатывающих. И как раз таки основной разбор делается не каждым модулем по отдельности, а централизованно. И при это подерживаются разные типы деректив.
Вот только ngx_conf_handler нефига не подставляет переменные, так как предполагает, что параметр может включать в себя спецсимволы обрабатываемые целевым модулем.
Добавить глобальную обработку — это дописать кусок кода в этой функции. В одном месте. А если добавить ещё один флаг для модулей, с помощью которого можно указать разрешено ли подставлять данные — то будет полная совместимость со всеми модулями, в том числе сторонних разработчиков.
Что же касается переменных $some_var_depending_on_host — то они зависят от контекста и по логике могут обрабатыватся разными модулями, друг с другом не связанными, потому и не разрашаются. Но при этом ничто не мешает допилить ещё один модуль, в который общие параметры могут складыватся и забиратся основным парсером (потребует правки модулей). Или добавив немного кода все в тот же глобальный обработчик ngx_conf_handler мы можем сами разрешать параметры с совпадающими именами.
Nginx это образец проблем которые могут оказатся у пользователя, если разработчик сделает хороший для себя код.
3. Приделать любую фичу к nginx-су проще простого. И именно как раз таки граблей там нет.
Здравствуйте, 11molniev, Вы писали:
1>1. Первоначально это был проект для личного использования.
Для личного использования Рамблера.
1>2. Вы серьезно или издеваетесь? Парсер конфига это один из модулей. И их может быть несколько последовательно отрабатывающих. И как раз таки основной разбор делается не каждым модулем по отдельности, а централизованно. И при это подерживаются разные типы деректив.
1>Вот только ngx_conf_handler нефига не подставляет переменные, так как предполагает, что параметр может включать в себя спецсимволы обрабатываемые целевым модулем. 1>Добавить глобальную обработку — это дописать кусок кода в этой функции. В одном месте. А если добавить ещё один флаг для модулей, с помощью которого можно указать разрешено ли подставлять данные — то будет полная совместимость со всеми модулями, в том числе сторонних разработчиков. 1>Что же касается переменных $some_var_depending_on_host — то они зависят от контекста и по логике могут обрабатыватся разными модулями, друг с другом не связанными, потому и не разрашаются. Но при этом ничто не мешает допилить ещё один модуль, в который общие параметры могут складыватся и забиратся основным парсером (потребует правки модулей). Или добавив немного кода все в тот же глобальный обработчик ngx_conf_handler мы можем сами разрешать параметры с совпадающими именами.
Вот у меня есть некоторое количество мини-сайтиков, все используют один и тот же конфигурационный файл. Я хотел было разрешить autoindex для некоторых из них путем map $host $autoindex { ... on/off }; ... autoindex $autoindex; — а вот нет. Причем ngx_http_autoindex_module точно выполняется одним из последних, к этому моменту $host гарантированно есть, но не работает.
1>3. Приделать любую фичу к nginx-су проще простого. И именно как раз таки граблей там нет.
Здравствуйте, Roman Odaisky, Вы писали:
RO>Здравствуйте, 11molniev, Вы писали:
1>>1. Первоначально это был проект для личного использования. RO>Для личного использования Рамблера.
Для личного пользования администратором Рамблера
1>>2. Вы серьезно или издеваетесь? Парсер конфига это один из модулей. И их может быть несколько последовательно отрабатывающих. И как раз таки основной разбор делается не каждым модулем по отдельности, а централизованно. И при это подерживаются разные типы деректив. RO>То-то такой велосипед при разборе параметра so_keepalive: http://trac.nginx.org/nginx/browser/nginx/trunk/src/http/ngx_http_core_module.c#L4133
RO>А был бы парсер, он бы сам всё сделал из грамматики в три строки наподобие: RO>
И тот же самый код был в этом самом парсере, вместе с горой другого кода
Это с одной стороны. С другой, ничто не мешает сдалать такой парсер и использовать его вместе разбора параметра отдельным модулем. Собственно простота подобного добавления функционала и кажется мне одним из критериев, которые позволяют говорить про код nginx-а положительно.
1>>Вот только ngx_conf_handler нефига не подставляет переменные, так как предполагает, что параметр может включать в себя спецсимволы обрабатываемые целевым модулем. 1>>Добавить глобальную обработку — это дописать кусок кода в этой функции. В одном месте. А если добавить ещё один флаг для модулей, с помощью которого можно указать разрешено ли подставлять данные — то будет полная совместимость со всеми модулями, в том числе сторонних разработчиков. 1>>Что же касается переменных $some_var_depending_on_host — то они зависят от контекста и по логике могут обрабатыватся разными модулями, друг с другом не связанными, потому и не разрашаются. Но при этом ничто не мешает допилить ещё один модуль, в который общие параметры могут складыватся и забиратся основным парсером (потребует правки модулей). Или добавив немного кода все в тот же глобальный обработчик ngx_conf_handler мы можем сами разрешать параметры с совпадающими именами.
RO>Вот у меня есть некоторое количество мини-сайтиков, все используют один и тот же конфигурационный файл. Я хотел было разрешить autoindex для некоторых из них путем map $host $autoindex { ... on/off }; ... autoindex $autoindex; — а вот нет. Причем ngx_http_autoindex_module точно выполняется одним из последних, к этому моменту $host гарантированно есть, но не работает.
Я же не сказал, что такой функционал есть, я сказал, что добавить его относительно простая задача, которая требует довольно небольшой правки кода.
Я не использовал map, но хочу отметить, что сопоставить хостам autoindex, вместо того что бы прописывать их в конфигурации хоста — в моем понимании странно. Конфигурационный файл становится больше только то и всего.
И самое главное: вы не можите использовать переменные для autoindex переменные не потому, что код написан криво, а потому, что autoindex вычисляется однократно — при прочтении конфигурации, а не для каждого запроса в отдельности. Проблема не в том, что как вы утверждаете "парсер каждой директивы сам занимается разбором аргументов, причем полностью в ручном режиме, даже без грамматики", а в том что этот параметр статический, не зависящий от запроса. И опять же ничто не мешает это поменять правкой кода в одном единственном месте (ngx_http_autoindex_module.c). Но то, что он статичен делает работу этого модуля чуть-чуть быстрей. Ничтожная величина — но таких величин множество и это один из факторов делающий nginx таким быстрым.
1>>3. Приделать любую фичу к nginx-су проще простого. И именно как раз таки граблей там нет.
RO>Динамическая загрузка модулей?
Здравствуйте, Alexéy Sudachén, Вы писали:
AS>То есть любой код не вписывающийся в рамки — говно. Ну да, мы же это уже вроде как выяснили? Вопрос — а судьи кто? Кто устанавливает рамки и почему все должны в эти рамки влезать. Как бы с сотрудниками одной конкретной компании всей понятно, у них всё это должно на уровне инструкций быть. Но у каждой компании, у каждого независимого проекта, у каждого индивидуала — рамки свои. Как результат суди все, и весь код говно. И к качеству кода эта характеристика обычно отношения не имеет.
Ну вот смотри, код писался в 2004м году. Что бы ввести довольно сложную и важную оптимизацию затрачено около 1 дня, при том что все оптимизированые конструкции были уже готовы, затронуто всего 5 файлов. Солюшн — доменная модель, довольно сложные сценарии, вагоны кода. Код довольно легко покрылся юнит-тестами. Итог работы — пара-тройка багов которые вылезли в регрешнах.
Второй пример — добавить кнопку на тулбар, связать её с формой, прикрутить обновления, событиями и тд. Убито три дня времени, модифицировано полтора десятка файлов, регрешны + дали пару десятков багов, на которые ушло еще от недели до двух + повторное тестирование и тд и тд.
Вопрос — какого хрена добавление кнопки на тулбар выливается в такую эпопею ?
Очень простой ответ — люди, которые писали эт часть , были очень трудолюбивыми и аккуратными — аккуратно и методично размножили сточки кода на пару сотен айтемов и сделали соответсвующие изменения в целой куче файлов.
Вместо того, что бы написать внятное обновление UI, ну скажем контроллер , с конфигурянием айтемов навроде
они написали несколько десятков строчек на каждый! айтем в тулбаре и родили сложную логику обновления UI. Чудовищный по размерам код, который только и занимается диспетчеризацией. Теперь вся работа в UI сводится к приседанию с этим кодом. Т.е. минимум половина времени разрабов тратится на код который вобщем то ничего полезного и не делает.
Так вот, первый код выглядит хуже некуда, но он очень качественный, позволяет вводить изменения.
А второй выглядит очень красиво и тд тд. Но это говнокод, потому что за время проекта не нашлось ни одного девелопера, кто бы смог побороть дублирование в этом коде.
Вобщем чисто теоретически, все зависит от способности читать код, а практически оказывается, что сложность самого кода растет намного быстрее, чем квалификация разработчиков, при чем нелинейно. Вот это и есть говнокод.
Здравствуйте, Protey, Вы писали:
V>>formatTag+=(unsigned char)chBuff[l]*1<<8 V>>что было переделано на: V>>formatTag+=(unsigned char)chBuff[l]*256
P>А криминал в чем ? В свое время, давным-давно правда, видел инструкции прямо инструктирующие делать сдвигами.
Шо, в самом деле, вместо умножения сдвиг делать ? Это инструкции образца 80х, когда компилер не умел оптимизировать.
Вот смотри, круть какая: (((a << 1)+a)+(a << 1))<<1
Посмотри, сколько людей сходу ответит что здесь делается.
I>А второй выглядит очень красиво и тд тд. Но это говнокод, потому что за время проекта не нашлось ни одного девелопера, кто бы смог побороть дублирование в этом коде.
Я вот только одного не пойму... это характеристика кода или таки девелоперов?!
I>Вобщем чисто теоретически, все зависит от способности читать код, а практически оказывается, что сложность самого кода растет
Практически оказывается что имеющиеся в наличии девелоперы говно?!
Re[12]: А вы видели код не говно ?
От:
Аноним
Дата:
23.04.13 14:52
Оценка:
Здравствуйте, Alexéy Sudachén, Вы писали:
AS>Практически оказывается что имеющиеся в наличии девелоперы говно?!
У твоего оппонента не может такого быть, ибо у них очень грамотное и правильное собеседование и плохие девелоперы его не пройдут. Что был твоим оппонентом не раз доказано здесь на форуме.
AS>>В общем, то что код 'пахнет', это не характеристика кода, это характеристика того кто 'нюхает'. I>Качество кода определяет вектор развития девелопера. Будет ли он т.н. бойцом с кодом или инженером. Востребованы почему то именно инженеры. Вот чудеса
Качество кода характеристика интегральная. Не бывает просто лучше или хуже. Как бы нет в природе лучшего вообще, есть лучшее в частности. С худшим ровно так же. ИМХО, руководителю то нефигво бы было это понимать )))
Твой посыл ведь можно понимать и так что человек, который может разобраться в сложно запутанном коде и распутать его до вразумительной сложности или хотя бы прибить матёрые баги, ничего толкового написать не может, а вот тот кто не может читать код сложнее чем из учебника — он ОГОГО какой инженер ))) То есть чем меньше 'натворить' может тем лучше )))) Тоже подход, хотя он и не работает.
Востребованы люди, которые без волшебного пенделя могут сделать свою работу в оговоренные сроки и в заданных ограничениях. Остальное романтика.
A>вообще С код не может быть хорошим по-определению, A>а С++ код там от С недалеко ушел. A>хотя там где COM интерфейсы его можно объяснить ограничениями COM (хотя зачем там вообще COM?).
A>собственно catch(int) в main() сразу намекает на качество кода
Самое смешное, что там не COM. А по мотивам. Обработка ошибок строго зачаточная. Хочется взять и все с нуля переписать. Но некогда, приходится так использовать
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
AS>>Практически оказывается что имеющиеся в наличии девелоперы говно?! А>У твоего оппонента не может такого быть, ибо у них очень грамотное и правильное собеседование и плохие девелоперы его не пройдут. Что был твоим оппонентом не раз доказано здесь на форуме.
потому что за время проекта не нашлось ни одного девелопера, кто бы смог побороть дублирование в этом коде — я придумал? Или это просто фетишь, который на самом деле нафиг никому не нужен, потому и не нашлось. )
Что до собеседований, дык я у него на собеседованиях не был, и кто его пройдёт, а кто нет — не знаю. Но по общему фону тусофки могу судить что 'грамотные и правильные девелоперы', ну те которые проходят собеседования, и программисты способные писать код — это таки разные люди )))
I>Вот смотри, круть какая: (((a << 1)+a)+(a << 1))<<1 I>Посмотри, сколько людей сходу ответит что здесь делается.
Э... и сколько же людей ответит что делает тривиальный код (a<<3)+(a<<1)? Ну... я даже не знаю ... наверное все, кто знает что такое << ? Не, ну правда, у вас что действительно настолько плохие программисты?!