Pull to refresh

Comments 147

И пока сферические программисты в вакууме пишут идеальный проект с соблюдением DRY, KISS и множеством других красивых слов, конкуренты с доделанным прототипом из говнокода и палок отъедают свой кусок рынка.
Такова история большинства ныне успешных компаний: говнокод, костыли, но они работают и за них платят деньги.
Это не красивые слова, просто рекомендации.
Хорошо, работает, и у меня много раз так бывало.
Просто потом самому не хочется дорабатывать это дерьмо, просто потому, что осознаешь, насколько все плохо.
Правильно, а потом это все передают индусам доделать, они не привередливые.
зы. Это личный опыт.
" Преждевременная оптимизация — корень всех зол. " Дональд Кнут (однако авторство некоторые причисляют различным легендарным личностям, но это не важно)
Возможно реализовывать систему кеширования и load-balancing для слабонагруженного проекта вначале глупо, но нужно писать так, чтобы потом это можно было безболезненно добавить.

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

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

Где-то так.
У вас на практике было что в любом случае «Преждевременная оптимизация — корень всех зол»?

По-моему, иногда, она очень даже уместна.

У большинства принято цитировать людей с умным лицом (хорошо, чтобы это были Стив Джобс, Джоель Спольски, ..., еще лучше если Д. Кнут, Д. Риччи,...).

image

P. S. Только цитировать...
640 килобайт хватит всем
Да сколько ж можно то…
Это был сарказм в тему о том, что не всегда великие люди глаголят истину. Но видимо, до большинства не дошло, ещё и карму слили.
Он эту фразу не говорил…
А люди все продолжают и продолжают ее спамить где ни поподя. Прочитайте оригинал, там другой смысл.
Полностью согласен. У меня вот сейчас «А-а-а-а-а! кошмар! паника!» из-за того что «преждевременно» не оптимизировали. А мне теперь много чего переделывать приходится.
А у меня наоборот — гораздо больше проблем с оптимизацией там, где изначально пытались «оптимизировать». А вот там, где код простой и понятный — и оптимизируется гораздо легче, причём точечных оптимизаций хватает за глаза.
гораздо больше проблем с оптимизацией там, где изначально пытались «оптимизировать».
Тоже стоит запомнить и усвоить…
Точно. Оптимизированный код — как обрезанное одеяло. Если этого не делать, то потом из бОльшего одеяла всегда можно сделать меньшее. А наоборот нельзя будет сделать. )))
Преждевременная оптимизация плоха тем, что она ухудшает понимаемость кода, и достаточно часто — очень сильно ухудшает. Мой опыт в профилировании и оптимизации показывает, что гораздо лучше сначала написать красивый, целостный, концептуально чистый и _понятный_ код — а уже потом профилировать его и ускорять узкие места. По факту узкие места почти всегда оказываются не там, где бы ты подумал изначально, и уж точно всегда их можно оптимизировать проще, чем писать изначально «оптимизированный» код.

Разумеется это не относится к выбору базовых алгоритмов и архитектуры (т.е. к таким вещам, которые потом будет сложно переделать).
Что лучше — в два-три раза больше более «понятного» кода или наоборот?
Не очень понимаю постановку вопроса. Чем кода больше, тем он менее понятен (если качество кода не меняется). Мне кажется это очевидно — чем больше объём информации, тем человеку сложнее её понять.
Что лучше — в два-три раза больше более «понятно написанного» кода или в два-три раза меньше кода, который делает то же самое, но менее «понятно написанного»? Вопрос.
Однозначно лучше первое. Программы пишутся не для компьютеров, а для людей, и основным приоритетом должна быть поддерживаемость кода. Ну, по крайней мере в реальных коммерческих проектах это так.
Полностью согласен. Эта фраза в основном относится к тем 97% случаев, когда программист начинает оптимизировать части кода, которые не являются никакими ботлнеками вообще. И делает он это потому, что знает хитрый алгоритм, а все мы понимаем как поднимается самооценка от классной реализации хитрого алгоритма!

Но при этом читаемость кода ухудшается на порядки! Потом даже сам программист продирается через дебри сложного кода, пытаясь вспомнить что же оно тут делает.
Если «хитрый алгоритм» — это всего лишь строчка из Hacker's delight, которую этот программист знает наизусть и пишет не задумываясь — то почему бы не написать? За время актуальности программы он её вряд ли забудет. А те, кто будет читать за ним — разберутся, и от этого их самооценка поднимется на порядок больше! И в мире будет больше классных алгоритмов и довольных программистов :)

while(a&(a+1)) a|=(a+1);
a++;

Да, 10 минут времени, сзади стоит красный от злости босс, а тебе разбираться вот с этим.
Я бы автора сей строчки убил и сжег.
Вообще-то я регулярно за время актуальности программы забываю, почему было принято то или иное решение, и как конкретная оптимизация работает. А удовольствия разбираться в чужом недокументированном коде я тоже не люблю.
Вот пример граблей, которые я сам себе сделал. Писал прототип, нужна была оптимальность. Я написал передачу в метод одного массива и в нем преобразование. Массив очень большой. Возможно съел бы всю память. И я придумал (заранее) не очень сложный, но хитрый алгоритм, который не делает копию, а преобразовывает этот же массив.

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

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

Любая оптимизация заранее — зло. Даже недорогая. Оптимизировать нужно только ботлнеки. А где они будут, выяснить можно только замерами.
Как говорил Дональд Кнут, «Кто вы такой? Что вы делаете в моём доме?». Ну, так он мне ответил, когда я его спросил.

xkcd.com/163/
«Оптимизация» и «чистота кода» — не только не одно и то же, но и в каком-то смысле взаимоисключающие вещи.
«Взаимоисключающую» часть оптимизации обычно встраивают в компиляторы и виртуальные машины и руками не делают.
Да ну?

Вообще-то, первый приходящий в голову пример такой оптимизации — это сильно специфический SQL-запрос напрямую через нативное API вместо ORM с доменной моделью.
Кому как. Мне — «линеаризация» циклов и инлайнинг коротких и однократно используемых методов.
Это вообще мелочи на общем фоне.
Note:
DRY, KISS и множество других красивых слов (SOLID, MVC...) — не то, что делает проект идеальным.
Для успешного проекта нужны грамотные программисты. С вами предельно согласен. А у большинства (чего греха таить, даже у «покорного слуги» (ц)) работает закон «20% знаний/квалификации/умения (нужное подчеркнуть) — 80% результата». А работает это у 95% «населения», остальные 5% просто спят или пишут документацию, которую потом никто не прочтет.

Признайтесь, если вы (обобщенно) одновременно тащитесь от написания кода, документации, планирования и проектирования, тестирования, исправления временами слишком рутинных багов, и всегда укладываетесь в срок — то я снимаю все шляпы, которые когда-либо у меня были.
UFO just landed and posted this here
Простите, что? DRY, KISS и прочие красивые слова сильно экономят время и сразу, и в будущем.
UFO just landed and posted this here
Будет ли это «будущее» — ещё не понятно. DRY, KISS и прочие красивые слова экономят время только тогда, когда требуют мало времени для применения, т.е. сидят уже в подкорке. Если их применение требует больших усилий, то они его больше тратят, чем экономят.

Стоит ли их применять — зависит от квалификации программистов.
С одной стороны я с вами согласен. С другой — если человек не знаком с настолько базовыми понятиями, ИМХО он никакой не программист. Кодер — возможно.
И именно поэтому порой так неохотно открываются исходники даже невыгодных проектов.
Ведь там же такой говнокод… И все это вдруг увидят… СТЫДОБА!
Тут вкралась неточность. Деньги платят все-таки НЕ за «говнокод и костыли», а за «хорошую систему». Просто заказчик редко понимает, что же именно он получил. И даже если понимает — деньги-то уже потрачены.
Никто не мешает используя Agile, KISS и DRY фигачить говнокод, другое дело, что нужно вовремя рефакторить. Только некоторые Челябинские программисты могут писать код, который сразу работает и не требует рефакторинга, и еще Чак Норрис.
Поэтому, я, без зазрения, занимаюсь рефакторингом, когда говнокод мешает решить ту или иную задачу. И функционал растет, и говнокод пропадает.
Ух как же в тему топик вечером вторника.
p.s простите
А что особенного в вечере вторника? В среду утром было бы уже не ок?
ИМХО по данному вопросу… Удобоваримый код — это прекрасно, но данную «вкусняшку» очень сложно реализовать в рыночных условиях труда, когда очень важно «урвать кусок рынка». Зачастую именно те, кто отправили «сырую», но рабочую версию в плавание добиваются большего. Мне порой кажется, что таким ходом можно даже не навредить. Ведь — отправив версию в релиз, разработчик (если остается в роли «поддержка ПС») получает время на оптимизацию кода, его упрощение и удобство… Но опять же зачастую это не так…
Удобоваримый код — это прекрасно, но данную «вкусняшку» очень сложно реализовать в рыночных условиях труда, когда очень важно «урвать кусок рынка».
Рыночный сектор вообще не может существовать без постоянной подпитки из нерыночного;-) На рынке надо писать сразу быстро и хорошо. Учиться и тренировать можно в общем только вне рынка;-)
UFO just landed and posted this here
От масштабов зависит. Крупный проект в дальнейшем невозможно модифицировать.
По хорошему если, то надо рефакторить куски системы. Иначе в какой-то момент её станет невозможно развивать.
Если сильно хочется, то можно, но такой ценой…
Странный совет даётся в статье. Мой опыт строго противоположный — прототип вырос в итоге в готовый проект, который пошёл в production.

Используйте только удачные конструкции, чтобы ваш пластилиновый ком в чистом проекте превращался в стальной каркас.
Что мешает использовать «удачные конструкции» в прототипе? Он мал, не содержит лишнего, его легко модифицировать/рефакторить. Почему исправления должны делаться в другом проекте?
Либо вы гений, либо никогда не делали больших проектов.
Все мы тут, конечно же, делаем исключительно гигантские проекты.
К чему сарказм? По-моему очевидно, что чем больше проект, тем сложнее сделать «сразу хорошо».
А что, большой проект на модули не бьётся?
А вы сами пробовали? или хотя бы участвовали? или хотя бы наблюдали?
Нет, что вы! 10 лет исключительно от хелловорлда до хелловорлда. Предыдущий хелловорлд, например, был 430К строк (на Python).
А в больших проектах типа Linux kernel — нет, не пробовал, не участвовал и даже не наблюдал.
Я на тему разбивания уже существующего большого проекта на модули… я наблюдал и участвовал слегка… геморрой ещё тот…
А я в своём предыдущем комментарии имел в виду нечто другое.

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

Взять вот нынешний проект, в котором я участвую. Текущий объём кода ещё только-только перевалил за 90К строк (часть на C, часть на C++), однако он изначально был разбит на независимые модули, так что даже если какая-то часть обрастёт говнокодом, всегда можно будет отрефакторить её совершенно независимо от остального кода.
Вот правильно разбить его на модули — и есть «сделать сразу хорошо. Вот как раз это и сложно, особенно при нынешней ситуации с требованиями.
Знали бы вы, сколько раз у нас менялись требования к текущему проекту %)

Вплоть до того, что один из ключевых компонентов изначально был задуман как долгоживущий демон, а теперь это запускаемая по требованию утилитка, логины/пароли пользователей изначально задумывалось запрашивать у стороннего демона, а теперь они передаются параметрами при старте утилитки, и вообще изначально часть писалась на питоне, потом поступило указание переколбасить на C++ (разрешив использовать QtCore), после чего сказали «никакого Qt, максимум STL», а потом вообще сказали «нет, размер бинарника демона не должен превышать 100К, так что давайте-ка на чистом C». Ну а потом, как я уже сказал, демон перестал быть демоном :)

И ничего не поплыло, всё по-прежнему стройно и красиво. Мне, конечно, лестно было бы думать, что мы — гении проектирования, но это как-то слишком уж самонадеянно. Или…?

По-моему нужно просто помнить одно: проектирование — это не просто один из этапов разработки. Проектирование — это процесс, не прекращающийся на протяжении всего жизненного цикла программы. Он никогда не должен заканчиваться. Меняются требования — тут же вносятся корректировки в архитектуру. До того, как в проект попадёт первая строчка «дополнительного» кода. Ну а если следовать принципу «сейчас вот тут прилеплю, а как-нибудь потом отрефакторим» — то тут, конечно, пиши пропало, ибо как показывает практика, это «как-нибудь потом» не наступает в 99.5% случаев.
Меняются требования — тут же вносятся корректировки в архитектуру.

Вот тут вам и повезло. В реальности (нашей) на это регулярно нет времени.
«There’s Never Time to Do It Right, But There’s Always Time to Do It Over» («Никогда нет времени на то, чтобы сделать правильно, зато всегда есть время на то, чтобы переделывать»).

Вы зря думаете, что ваша реальность чем-то отличается от чьей-либо ещё. Реальности у всех одинаковые. А вот подходы — разные.
Времени переделывать тоже нет.

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

В принципе, конечно, есть такой подход: сменить заказчика. Но кушать-то тоже хочется.
>Понимаете, очень радостно думать, что есть волшебный подход, который позволит объяснить заказчику, который хочет конкретную мульку завтра, что чтобы сделать ее правильно, нужна неделя.

Вы смешиваете понятия. Есть то, чего хочет заказчик, а есть объективные сроки, когда это может быть сделано (хоть «на коленке», хоть «как полагается»). Это ни хрена не эквиваленты, и не нужно подменять одно другим.
Срок, насколько я понимаю, называет исполнитель, а не заказчик. Т.е. вы сами называете срок «сделаем к завтра» (прикидывая тяп-ляп на коленке) вместо того, чтобы назвать срок «через неделю» (чтобы как полагается), я правильно понимаю? А зачем?

Только не говорите мне, что заказчик сам вам за день до сдачи проекта говорит «а теперь мы ещё добавим вот это, вон то и ещё вот это сбоку, и чтобы всё к завтрему», а вы молча соглашаетесь… о_О

Вы поймите, он от вас никуда не денется. Если даже рванётся на сторону, то он точно проиграет по времени, а не выиграет, т.к. сначала нужно найти другого подрядчика, договориться с ним, передать ему проект, после чего подрядчик будет разбираться с проектом, и только после всего этого сможет начать добавлять нужные фичи. «К завтрему» точно не уложится. Да и в неделю — вряд ли.
Это вы так думаете, что никуда не денется. А я видел реальную ситуацию, когда было две заявки — одни доработать «на коленке», а другие — «сделать, как надо». Выбор, очевидно, туда, где меньше сроки и стоимость.
Если сама заявка тупо на «доработать», то к теме нашего разговора она имеет весьма опосредованное отношение. Мне казалось, что мы тут в основном о долгоиграющих проектах, когда заказ уже у вас, и вдруг «срочнанахбыстранахпрямосейчаснах!» понадобилось добавить то, о чём ранее и разговора не было.
Мы о долгоиграющем (5+ лет) проекте с поддержкой, где за выполнение feature request в рамках поддержки есть конкуренция.

И это как раз и есть та самая ситуация, когда исходные требования уже изменились настолько, что надо менять архитектуру, но времени на это никто не выделяет.
Т.е. допустим вы разрабатывали проект 5 лет, а потом на доработку объявляется конкурс, что ли?
Т.е. фактически это уже не ваш проект. Новый контракт, новые условия, новые требования и потенциально новая команда. Т.е. ровно то, что я говорил выше.
Тем не менее, именно таким образом в коде и появляется то, чего там быть не должно.
Это понятно. Вот только разговор изначально шёл о совершенно другой ситуации :)
Между ними далеко не такая четкая граница, как нам бы хотелось.
There’s Never Time to Do It Right, But There’s Always Time to Do It Over
Первое — расплывчато, второе — легче обосновывается объективно наличествующей крайней необходимостью (с регулярностью граблей постоянно откуда-то возникающей, несмотря на то, что её теоретически не должно быть).
Видите ли, чем больше проект, тем менее четкие требования. Соответственно менее ясная структура. Битьё на модули естественно никто не отменял, но оно — не серебряная пуля, вы знаете.
>Видите ли, чем больше проект, тем менее четкие требования.

Вижу, прекрасно вижу. См. пример из моего текущего проекта чуть выше.

Я там ещё забыл добавить (а время, отведённое на редактирование, истекло, пока я печатал), что изначально было требования «работаем только на отдачу данных», потом добавилось «теперь ещё и приём», плюс спектр принимаемых/передаваемых данных постоянно менялся. Да и до сих пор меняется :)
Арагорн не одобряет вашу неосведомлённость.
А Боромир — вашу память на лица
Нет, это Брэд Питт.
Нельзя просто так взять, и запомнить лица.
Точно, это Боромир :)
Прототипирование ни в коем случае не является инструментом реализации. Это инструмент проектирования. С помощью прототипирования можно лучше проработать требования, но как таковой альфа-версией продукта прототип являться не может.
Чем является проектируемая система — полноценным продуктом или прототипом, нужно определяться заранее. До того, как это будет создано.

Жаль, что так гладко только на бумаге. В реальности нас жестко ограничивают ресурсы и делать все правильно мало кому удается.
Развитие прототипа в production — не прихоть ленивых программистов, а требование заказчика. Они видят работающую программу, которую чуть-чуть надо подкрутить. «Что? Какой ещё прототип, все же работает? Вы собираетесь всё переписывать?! Давайте без глупостей, мы не собираемся 2 раза оплачивать одну работу». Как-то так.
Я как программист и не как менеджер проекта считаю, разумеется, что хороший код — наше все. Но теоретически если есть хорошая модульная архитектура, следующая принципам SOLID, то отдельные части системы, более близкие к листьям дерева зависимостей, могут быть реализованы с костылями и фекалиями. В таком случае такой код не будет воздействовать на остальную систему, будет полностью локализован и легко заменяем другим кодом, когда для этого будет возможность.
На мой взгляд, это идеальная стратегия разработки.
Если продукт развивается, и требования не стабилизированы, то рефакторинг потребуется в любом случае; о каком идеальном коде может быть речь?

Продукт должен решать проблемы заказчика. Идеальность или неидеальность кода — это проблема разработчика, за него заказчик в общем случае платить не обязан. Так что проблема несколько раздута, да и пост откровенно ни о чем.

Вы написали какой-то кусок кода, проверили его — он делает точно то, что вам нужно. Далее, реализуем другую фичу, прикручиваем её туда же, и понеслась…

А все потому, что не нужно бросаться с места в карьер реализовать отдельные фичи по отдельности, а сначала разработать высокоуровневый дизайн, рассматривая программную систему как совокупность взаимосвязанных фич.
И часто вы встречаете таких заказчиков с такими ТЗ, которые позволяют сходу полностью описать дизайн? если да, я Вас завидую…
Рефакторинг… Автору нужен рефакторинг. Прототип создается для уточнения ТЗ. После формирования окончательного ТЗ прототип рефакториться исходя из требований задачи…
А просто так взять и быстро написать красивый код можно… Но для этого надо иметь колоссальный опыт разработки (или просто быть гением) и знать предметную область как свои пять пальцев…

А индусы… Красивый код это понятный код, а не красиво форматированный… И давайте считать тут индусами не титульную нацию Индии, а тех кто пишет коряво и позорно…
Так индусы — это и вообще не нация. Титульная нация Индии — индийцы.
Рефакторится или выкидывается и переписывается — это уже смотря по обстоятельствам…
Многие говорят, что прототип правильно выкидывать и защищают это положение подобно догме. Но по мне — это вопрос скорее идеологический. Если прототип хорошо отрефакторить сразу, можно вполне с ним и дальше работать. Но если делать «отложенный рефакторинг», тогда возникает то, что автор описал в посте. Если откладываешь рефакторинг, то лучше сразу отложить вместе с ним и прототип, и действительно создать новый проект.
Прототип же это не шапкамизакидаем! Это просто некий образец, который делает лишь малую часть того, что нужно, а остальное заделано заглушками.
Проблема в том, что очень многие не понимают того, что такое «прототип», и думают, будто это — кое-как наспех сляпаная программа, которую когда-нибудь потом, в светлом будущем, перепишем.

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

Кроме того, нужно различать прототипы, которые служат основанием для разработки, и выбрасываемые прототипы. Первые должны делаться по всем правилам, вторые могт быть написаны как угодно (хоть на другом языке и в другой среде, что, кстати, зачастую и делается), лишь бы они были дешёвые, делались очень быстро и помогали получить ответ на нужный вопрос.
Ведь уже описано же, и в Pragmatic Prorgammer, и в Code Complete. Зачем еще раз жевать-то?
Code Complete устарела, ибо написана ещё ДО появления рефакторинга.
Эээ?

Opdyke, William F.; Johnson, Ralph E. «Refactoring: An Aid in Designing Application Frameworks and Evolving Object-Oriented Systems». Proceedings of the Symposium on Object Oriented Programming Emphasizing Practical Applications (SOOPPA). ACM. — 1990
Griswold, William G. Program Restructuring as an Aid to Software Maintenance. Ph.D. thesis. University of Washington. — 1991
Opdyke, William F. Refactoring Object-Oriented Frameworks. Ph.D. thesis. University of Illinois at Urbana-Champaign. — 1992
MaxConnell, Steve. Code Complete, 2nd edition — 1993.
Fowler, Martin. Refactoring — 1999.
MaxConnell, Steve. Code Complete, 2nd edition — 2004.

Ну и на закуску: «The foundations of what we refer to these days as refactoring comes from the Smalltalk communities. However the metaphor of factoring a program was also part of the Forth community. Bill Wake dug out the first known printed mention of the word „refactoring“ in a Thinking Forth, a 1984 book by Leo Brodie. We're pretty sure that this usage didn't pass from the Forth community to the Smalltalk community, but developed independently. „

По крайней мере механизмов рефакторинга в Borland C++ Builder и в других IDE в 90-х годах не было.
Рефакторинг — это подходы и методики к изменению и переписыванию кода так, чтобы он лучше читался. Плюшки конкретных IDE в данном случае служат конкретно этой цели, но рефакторингом вы можете и в «Блокноте» заниматься :)
рефакторингом вы можете и в «Блокноте» заниматься :)
… имея бесконечные временные ресурсы. И на работу за 7 километров тоже можно каждый день пешком ходить :). Но при наличии бесконечных временных ресурсов и рефакторинг и оптимизация вообще теряют смысл. Как раз наличие плюшек по части рефакторинга и автоформатирования и заставило меня перестать кодить на Java в FAR и пересесть на IDE. Как раз именно механизированный рефакторинг — «плюшки конкретных IDE» — дал возможность сначала писать программу, а потом улучшать дизайн, что привело к статьям на тему «дизайн умер как класс».
Далеко не всякий дизайн можно улучшить.
Ну да, пока неудачное разделение проекта на модули в пару-тройку кликов мышкой улучшить нельзя…
Ну я вам о теоретическом понятии, как у Фаулера.
Чушь. Если какой-то конкретный язык в силу своих (задуманных) особенностей крайне плохо подвергается ручному рефакторингу, это не значит, что все языки такие. Никогда не пользовался и не испытывал необходимости в полуавтоматизированном рефакторинге в Ruby. В худшем случае мне была нужна глобальная замена или sed.
Два лучше всего полуавтоматически рефакторящихся языка — это Java и C#. Основная польза от рефакторинга — возможность менеджить «в одну харю» в десять раз больше кода.

Не знаю, как с динамичностью типизации в Ruby, но Javascript из-за динамического и «утиного» характера типизации должен рефакториться сильно хуже.

Именно ручной рефакторинг, на мой взгляд, — это или хардкор или чисто академическая вещь или малое по объёму (но не по трате усилий) дополнение к полуавтоматическому.
Вся суть Руби в том, что его динамичность позволяет уменьшить количество написанного кода в десять раз, генерируя шаблонные методы автоматически. Вместо того, чтобы расписывать одну и ту же логику, которую нельзя зашарить средствами языка, руками, Ruby позволяет сделать это при помощи самого себя.

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

Ну и да, первое правило рефакторинга — тесты, второе — rely on compiler. Все остальное — приятные бонусы.
То есть сама возможность изменения кода — «приятный бонус» к тестам и " rely on compiler"?
Возможность изменения кода есть изначально, иначе бы вы его писать не могли.
По-моему, тесты и «rely on compiler» — это правила не столько рефакторинга, сколько Continuous Integration и XP вообще.
Это мнение неверно.

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

То, что у CI и XP схожие инструменты, говорит лишь о том, что у них и у рефакторинга схожие подходы.
[Opdyke, William F. Refactoring Object-Oriented Frameworks. Ph.D. thesis. University of Illinois at Urbana-Champaign. — 1992] и [Opdyke, William F. Refactoring Object-Oriented Frameworks. Ph.D. thesis. University of Illinois at Urbana-Champaign. — 1992] — это, как видно даже из названия, тезисы кандидатских диссертаций;-).

[Opdyke, William F.; Johnson, Ralph E. «Refactoring: An Aid in Designing Application Frameworks and Evolving Object-Oriented Systems». Proceedings of the Symposium on Object Oriented Programming Emphasizing Practical Applications (SOOPPA). ACM. — 1990] — это, по данным того же источника, «The first known use of the term „refactoring“ in the published literature». Там же: "Martin Fowler's book Refactoring: Improving the Design of Existing Code[3] is the canonical reference."

Так что до Фаулера рефакторингом как серьёзной темой практически не занимались. «Code Complete» появился сильно раньше книги Фаулера.
Спасибо, кэп. И что?

Но вообще, чтобы вы знали, в Code Complete 2ed есть целая глава (24-ая), посвященная рефакторингу. Так что ваше утверждение про «устарела» заведомо ложно.
Интересно, какие ещё отличия есть в «2ed» по сравнению с первым изданием и какова их доля в общем объёме книги…
sarcasm mode on
Хабрахабр — соообщество специалистов.
sarcasm mode off

Извините, но это ад.
Можно уточнить, кто это всё будет оплачивать и накойхер?
Мне кажется, здесь происходит путаница между понятиями прототип и proof of contept.

То что вы описали как «написали какой-то кусок кода, реализуем другую фичу, прикручиваем её туда же…» и «пластилиновый ком, на который со всех сторон налеплены куски, и он готов вот-вот развалиться» называется proof of contept. Он нужен, чтобы сказать: «О, работает!». Грубо говоря, proof of contept умеет делать все, что должно делать ваше приложение, но через заднее место, только сделан он на коленке и архитерно убог.

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

Что вы думаете о том, что есть «горизонтальные» (поведенческие), «вертикальные» (структурные), throwaway и эволюционные прототипы?

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

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

Вот тот, кто сможет объяснить — тот гений. Ждём статьи о том, как это сделать.
Данный совет применим только к неопытным разработчикам, которым нужно где-то этот опыт получать, а ничего лучше повторения еще не придумали.
Остальных же можно отправить почитать Спольски и Фаулера, ну или порекомендовать скачать Netscape (поясню: рефакторинг спасает даже самый плохой код, а Netscape потерял рынок из-за решения все переписать с нуля).

У разработчика нет такого, что «я работаю над прототипом, накидаю говнокод; я работаю над релизом, пишу правильно». Нет, все разработчики просто пишут код. Одни хорошо, другие плохо. И если развивающийся разработчик может написать вторую версию на 30% лучше, чем первую, то опытный — не больше, чем на 10% (цифры — мое IMHO).
И если развивающийся разработчик может написать вторую версию на 30% лучше, чем первую, то опытный — не больше, чем на 10% (цифры — мое IMHO).
О! Круто! Парадоксальность формулировки способствует запоминаемости.
Вы осознаете, что ваша статья как раз и является примером говнокода?

1) плохая структура
2) отсутствие конкретики
3) непроработанная аргументация
4) ненормативная лексика

Это я к тому, что надо начинать с себя.
А уже потом поучать других.
При этом трудно отрицать, что протопип уже набирает плюсы :)
Что как бы намекает: А судьи кто?
Мне по определению стыдно за код который написал до сегодняшнего дня. И так каждый день…©
На картинке изображен индус, но рядом код с русскими комментариями. Миф разрушен.
Так автор из ИДЕ скриншотик делал.
Что по поводу говнокода — вот shitcode.r12.railsrumble.com/ написали на конкурсе railrumble. Хотелось бы знать ваше мнение насчет проекта. Имеет право на жизнь или нет?
Не использовать прототип как исходный код — здравая идея. Лучше сделать прототип и потом с черновика переписать на чистовик.

Для себя давно выработал ряд правил.
Делается прототип в легком на подъем окружении, чтобы выкинуть было не жалко. Если что-то в прототипе не понравилось — тут-же выкидываешь начинаешь новый. Как только намечается тенденция застревания — откладываю задачу, если кончено удастся пересилить себя от соблазна продолжать есть кактус. Остановка — переключаюсь на другие задачи. Потом, когда все успокаивается и появляются новые идеи — возвращаюсь к брошенной задаче и делаю по-другому. Часто идее или задаче или проблеме надо дать отлежаться. Как говорится: ждите отстоя пива…

Данный метод часто применяю для создания прототипа верстки.

Очень важно иметь всегда под рукой запас средств дешевого прототипирования. Если ничего нет — блокнотик.
UFO just landed and posted this here
Ага, шаблон дизайна «потом вернуть переменную обратно».
Экономят память, занимаемую переменными…
Кстати, если бы писали в машинных кодах для Электроники БК-0010 (процессор K1801BM1A, в котором не было команд умножения), то такая оптимизация была бы более чем уместной.
Капитанская статья. А слабо написать КАК это провернуть в реальном продакшене?
Абсолютно не согласен. Вот сделаете вы рядом финальную версию «в камне». Через годик требования опять поедут, и ваш камень опять превратитсят в г.

Сложность в том, что мы должны уметь писать софт адаптивно. В том числе и уметь отрефакторить прототип. А потом опять сделать код некрасивым и опять отрефакторить и так далее.

Задача сложная, но очевидно, что она не решается без набора авто-тестов. Это пункт номер 0.
Я думаю, что любой код можно отрефакторить. Это нормально сначала прототипировать, а потом постепенно делать код проще и лучше. Хотя это требует больше квалификации, чем переписывание с нуля. Единственная проблема — убеждение некоторые заказчиков или менеджеров, будто без рефакторинга затраты времени могли бы быть меньше. Напротив, чем чаще он делается, тем меньше времени на него нужно и ускоряется общий процесс разработки.
Я думаю, что любой код можно отрефакторить.

Только это не всегда дешевле, чем написать с нуля.
Кто из «великих» (в одном из недавних переводов на Хабре) говорил, что самый хороший код он видел в провалившихся стратапах?..
«Психбольница в руках пациентов»
Началось с «Фермы в руках животных»…
Sign up to leave a comment.

Articles