Войти
ФлеймФорумПрограммирование

Что не есть "говнокод" ? (4 стр)

Страницы: 13 4 5 612 Следующая »
#45
13:04, 25 янв. 2012

fsmoke
> ЗЫ
>
> бедные студенты-программеры, всегда было смешно смотреть
Кармак и КО смотрят на тебя брутальным взгядом свиборга и потихоньку пишут код:)


Насчет того почему говнокод ненужен надо читать не в совершенном коде а в книгах по рефакторингу, там на пальцах объяснят что это такое, почему оно появляется, зачем его менять, и почему говнокод несовместим с долгосрочными проектами


#46
13:27, 25 янв. 2012

war_zes
> Кармак и КО смотрят на тебя брутальным взгядом свиборга и потихоньку пишут
> код:)
я ждал, что кот-то приведет Кармака в пример - но есть один нюанс Кармак не программер, он руководитель - ну да он чето там пишет больше для души - эксперименты проводит - но бабло он рубит как руководитель, а не как программер.

war_zes
> и почему говнокод несовместим с долгосрочными проектами
да с этим согласен - говнокод ужасно поддерживать.

По поводу долгосрочных проектов: вот опыт почему-то говорит другое - интеллекту 17 лет!!! И писался он, когда львиной доли всех этих вумных книжек не было. Чет в последнее время много учителей развелось - и каждый так и норовит указать мне то, как я должен писать :)). Хотя я в своей жизни реализовал проектов больше, чем эти многие писаки-философы.

#47
14:05, 25 янв. 2012

fsmoke
> По поводу долгосрочных проектов: вот опыт почему-то говорит другое - интеллекту 17 лет!!! И писался он, когда львиной доли всех этих вумных книжек не было.
За 17 лет можно собрать неплохую клиентскую базу.
Да и чего ты зациклился на этой "интеллект" ? У нас в компании тоже был говнокод, куча кода на асме, С++ вперемешку с Си, куча дубликатов и глобальных переменных, никакого стандарта, отсутствие документирования. У начальства одна мысль заняться рефакторингом ядра вызывала панический страх.

Результат: система развивается медленно, и не вверх, а в ширь; порог ввода новых сотрудников в "курс дела" - занимает много времени. Скорость работы движка системы была критичной, но новых алгоритмов не предлагалось, так как в таком виде невозможно было понять, как все это работает. Самое смешное, что все можно было почистить, но у меня сложилось впечатление, что мой шеф своим единственным преимуществом считает знание всех подводных камней, приобретенного за годы копания в этой лапше. Стоит только навести порядок, как сразу он станет "заменяемым".

#48
14:17, 25 янв. 2012

fsmoke
> но есть один нюанс Кармак не программер, он руководитель
Да, вот только он был программистом когда купил свою первую феррали

#49
14:25, 25 янв. 2012

war_zes
> Насчет того почему говнокод ненужен надо читать не в совершенном коде а в
> книгах по рефакторингу

Можете порекомендовать любимых авторов?

#50
14:41, 25 янв. 2012

war_zes
> Да, вот только он был программистом когда купил свою первую феррали
Да это так. Но приведи пример, конторы, которая платит такие гонорары сейчас простым программистам, особенно в России.

Маг
> и не вверх, а в ширь
в сфере сист. безопасности  - это как раз главное, кстати :)

#51
14:47, 25 янв. 2012

Kartonagnick
> Можете порекомендовать любимых авторов?
Мартин Фаулер. На первой странице еще писал.
Читай "Refactoring: Improving the Design of Existing Code"

#52
15:11, 25 янв. 2012

RPGman
> Можете порекомендовать любимых авторов?
вот его и читаю
RPGman
> Мартин Фаулер. На первой странице еще писал.

#53
15:33, 25 янв. 2012

fsmoke
> Так что говнокод в софте - не говорит о том что архитектура софта плохая.
Так вы определитесь что такое ковнокод.

Тезис1: "говнокод" == не_читабельный код. Его трудно сопровождать, потому что хрен проссышь, чего и как он делает. Например: тупые имена, ни одного комментария, ещё и размазано это все по всей архитектуре.

Тезис2: "говнокодом" код делает не_читабельность, и переосложнение самих алгоритмов. Когда вместо того, что бы "разделять и властвовать" - лепят все в одну кучу, с тупыми именами, без единого комментария.

Тезис3: говнокод, это неоправданно усложненный код. Понимание работы которого требует значительных умственных затрат, дальнейшее развитие которого приводит к повышению сложности понимания алгоритма. Что и приводит в какой то момент к тому, что программист перестает понимать, что, и как он делает.

А то, о чем вы говорите, имхо больше смахивает на принцип KISS. И непосредственно к говнокоду отношения не имеет. Продукт созданный по принципу KISS так же может быть хорошо понимаемым и читабельным. Дальше можно не читать ;)

****

Я вам пример один приведу. Некая сущность (условно назовём её сервером) получает на входе очередную порцию данных.
Эта порция может являться очередной порцией "простых данных", или хранить внутри себя "часть управляющей последовательности".

И все это идёт вперемешку: "простые данные" + "кусок управляющей последовательности". Задача сервера - вычленить в полученной порции признак наличия управляющей последовательности. И если он есть - следующие порции проверять на наличие "продолжения управляющей последовательности". И так, до тех пор, пока не будет получена вся последовательность. Либо, пока очередной кусок данных не покажет, что пришедшие данные не являются упр. последовательностью.

Представьте себе, что есть некий скрипт, имеющий формат функции: тип ИмяФункции (аргументы). И вот сервер должен распознать среди общего хлама пришедшую управляющую последовательность, и выполнить её. Причем "управляющие последовательности" были добавлены в самый последний момент, и архитектура изначально не было на такое рассчитана. Попытка добавить данную возможность топором очень быстро привела к переосложнению понимания самого алгоритма. Я просто начал переставать понимать, что делаю. Вторая попытка - я блок-схемки рисовал, со всякими стрелочками и ромбиками, и вводом дополнительных переменных.

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

В итоге, получилось решение на уровне самой архитектуры. Новый класс был внесен в общую архитектуру в нужном месте. Благодаря инкапсуляции сложность проекта резко упала. Сразу снова все стало просто и понятно. В тоже время принцип анализа поступающих данных стал очень прост и гибок. Что позволило парсить куски на предмет самых "необычных" управляющих последовательностей. Но самое главное - задаток на будущие. Подход позволил легко добавлять "новые правила", по которым можно будет вычленять ещё даже не существующие а потому неизвестного строения последовательности.

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

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

Что касается самого кода - ну пусть, первоначально он будет каким угодно. Но неужели так трудно сказать программисту: Почисти код. Дай красивые имена, если ты этого ещё не сделал. Поставь комментарии. В общем, сделай так, что бы код был максимально читабельным.

То есть, не нужно делать глобальный такой рефакторинг, но элементарную чистку кода, что бы он был "благо ухоженным" все равно делать надо.

Придёт новенький в проект. Ему на пальцах объяснишь, что делает узел. А дальше он читает прототипы, он читает реализации. И он не должен бегать каждый 5 минут к товарищам, и отвлекать их: "а что здесь делается?"

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

*****

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

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

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

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

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

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

Однако сама по себе KISS не делает код говнокодом.

Говнокодом код делает не_читабельность, и переосложнение самих алгоритмов. Когда вместо того, что бы "разделять и властвовать" - лепят все в одну кучу, с тупыми именами, без единого комментария.

#54
15:34, 25 янв. 2012

Не-говнокод: который написан мною менее недели назад. Всё остальное - говнокод.

#55
15:59, 25 янв. 2012

Kartonagnick
> А то, о чем вы говорите, имхо больше смахивает на принцип KISS. И
> непосредственно к говнокоду отношения не имеет. Продукт созданный по принципу
> KISS так же может быть хорошо понимаемым и читабельным. Дальше можно не читать
> ;)

дальше не читал, сорри не осилил :)) , позже прочту

Да здесь не в KISSе дело - смотри пример: система внешне выглядит круто - апи простое и понятное - допустим простой обмен интерфейсами - все логично и нормально, документация в полном порядке. Но когда открываешь исходники ядра - где эти все интерфейсы и механизмы реализованы - то там :

Kartonagnick
> не_читабельный код
Kartonagnick
> переосложнение самих алгоритмов
Kartonagnick
> неоправданно усложненный код
Kartonagnick
> тупые имена, ни одного комментария, ещё и размазано

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

#56
16:36, 25 янв. 2012

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

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

- знаешь, чем отличается профессионал от любителя?
- чем?

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

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

Но между стройкой и программированием есть одна большая разница: на стройке сделали красивую хату, и ушли. И не важно "что там внутри, во всех этих мелочах под обоями". Главное деньги получить, и успеть дойти до забора.

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

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

#57
18:41, 25 янв. 2012

Kartonagnick
> Максимально быстрый результат.
да все верно :)

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

Kartonagnick
> Нужно, например, новый функционал повесить.
Kartonagnick
> И как новеньких в курс дела вводить.

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

Поддержка - да если находился косяк в ядре, это был пипец - но на это были специально выделенные программеры :))

Понимаешь и эта схема работает - годами !!

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

#58
19:44, 25 янв. 2012

fsmoke
Разбить сложную задачу до уровня простых модулей, которые смогут осилить низкооплачиваемые говнокодеры - это не совсем "оно".
Ты просто аккуратно собираешь свою систему их черных ящиков, принцип работы которых тебя не интересует и себестоимость которых мала.
Это то же самое программирование, а не говнокодерство, но на более высоком уровне.
Принцип индусов в Майкрософт.

#59
23:10, 25 янв. 2012

fsmoke, это сработает, если архитектура сама по себе красивая и четкая.

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

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


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

Я приведу пример:

Есть два логических устройства (паттерн адаптер): CDev_In и CDev_Out. Это соответственно ввод и вывод.
Они могут иметь какие угодно методы (это не важно), важно, что они обязаны иметь метод GivMeData() и AcceptData() соответственно.
Как именно работают эти черные ящики - архитектурное сооружение вообще никак не волнует. Потому что оно (сооружение) взаимодействует только с этими двумя методами.

Первый метод "добывает" данные, второй соответственно их "выводит". Архитектурное сооружение не знает каким образом данные "добываются", и каким образом они "выводятся". Это - личная трудность самих черных ящиков. Фактически, под "вводом" и "выводом" на самом деле может подразумеваться что угодно. Логика полностью зависит от этих логических устройств.

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

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

Далее, уже конструируется деталька конструктора лего, я называю её "мост":

template<class Dev_In_t, class Dev_Out_t> class TDevIO: protected Dev_In_t, protected Dev_Out_t 
{
    //Весь паблик интерфейс является либо пабликом самого TDevIO, либо те методы предков, которые TDevIO захочет сделать публичными.
    //здесь методы, из разряда ввод-вывод. То есть, такие, которые возможно осуществить только имея знания о том, как данные добыть, и как отобразить
    //причем ввод-вывод понятия не имеет как именно данные будут добыты, и как именно они будут отображены. Он не зависит от логики работы и ввода, и вывода
};

Далее, в целевом проекте я делаю класс-специализацию:

class CConcreteIO: public TDevIO<CDev_In, CDev_Out> 

Это нужно только для того, что бы избавить "вызывающую сторону" от подробностей реализации. Вызывающей стороне, совершенно не интересно и не нужно знать, на чем базируется TDevIO, и вообще о его существовании. Достаточно только знать, что CConcreteIO гарантированно имеет методы ввода, вывода, и ввода-вывода.

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

В целевом проекте я просто делаю: #include "CConcrete.h" и спокойно работаю.
Это и есть моя законченная деталька конструктора, логику которой я могу изменять как угодно, путем замены деталек, из которой она состоит.
И общее архитектурное сооружение даже не заметит подмены. Для проекта в целом это будет безболезненная процедура.

Однако, темы проектирования архитектуры и говнокода - это же перпендикулярные темы. Это далеко не одно и тоже.

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

Однако:

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

2. Чем важнее деталь, тем более ответственно нужно к ней подойти, имхо. Ну то есть, нет беды, если кто-то сделает через жёпу малозначительный узел. А вот содержать ядро архитектурного сооружения в чистоте и опрятности - задача нужная. Ибо проблемы, которые могут в нем возникнуть, могут оч дорого потом обойтись. Если ненароком задеть инкапсуляци/инвариант, то весь конструктор Лего рискует развалится, как карточный домик.

3. Вы разрабатываете продукт, который до вас годами запиливался. То бишь, его идея, его API, архитектура и тп - все это было вам уже знакомым. А вот если бы вы разрабатывали его полностью с нуля, ничего не зная даже о том, какое там нужно API прикрутить, то не факт, что вы бы делали продукт быстрее, чем те гуру, что за два года "сделали красиво, но мало". Они же делали с нуля все.

Страницы: 13 4 5 612 Следующая »
ФлеймФорумПрограммирование

Тема в архиве.