Как стать автором
Обновить

Комментарии 170

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



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

Софт для космических аппаратов и систем жизнеобеспечения, по идее должен быть написан идеально.
Если по-честному, то между «Are you done yet?» и «Good code» надо протянуть стрелку «Да, и опоздали на пять лет и вложили в десять раз больше ресурсов». :) Проблема в том, что, во-первых, бизнес в большинстве своём не может себе позволить такую задержку, и, во-вторых, не хочет тратить столько ресурсов на получение идеального кода. Обычно это экономически нецелесообразно. Космос и жизнеобеспечение — здесь исключение, потому что первый, второй и третий приоритеты занимают надёжность, надёжность и надёжность.
так это нормальный, опытный подход к разработке. быстрое прототипирование (говнокод) и последовательное улучшение с рефакторингом почаще.
«все сразу по правильному» — делается только при избытке бабла, и то не всегда оправдывается.
действительно узнается, классический пример фейсбук — чтобы идея заработала достаточно было говнокода в первой версии.
Здраво. Но как не зря говорится — нет ничего более постоянного, чем временное. В реальной жизни на рефакторинг времени может просто не остаться, а потом все это превратится в снежный ком. По возможности лучше учиться сразу делать хорошо. И потом все относительно, может быть ваш говнокод для кого-то суперархитектура и наоборот.
На рефакторинг как раз время не остается, если всегда пытаться делать хорошо. Такой вот странный парадокс. Пример с меню из статьи очень хорошо показывает, что иногда нет смысла что-то делать на отличненько, пока не станет понятно, что это действительно нужно. А то получится, что сделали не просто хорошо, а великолепно, но это нафиг никому не нужно.

Другими словами, идеальный код, как бы грустно это не звучало, противоречит требованиям бизнеса. Бизнес продает решение, а не качество кода. Качество помогает в высококонкурентной среде, и стремиться к нему нужно, но никогда не перегибать палку.
Между идеальным кодом и говнокодом есть множество промежуточных звеньев. Хороший программист умеет набросать хороший (но не идеальный) код для проверки идеи быстрее, чем он бы или плохой программист писали говнокод. Когда, к примеру, выделение метода занимает у человека полминуты, этот подход становится предпочтительнее копипасты, даже если код всего дважды повторяется.
Пускай даже не быстрее, а столько же по времени или на несколько процентов дольше.
Два типа мышления. Вася — продавец, он думает про то, как срубить бабла и, следовательно, про маркетинг, себестоимость и т.д. Петя — художник, он может очень хорошо выполнять свою работу и написать совершенный код.

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

Поэтому на стадии тестирования надо писать быстро, лишь бы работало. Если идея себя оправдает, то уже переписать как надо. Если не оправдает — в топку.

Все правильно написано в статье.

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

Вася и Петя одновременно начали писать один и тот же продукт.

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

Чтобы выйти на рынок раньше, Петя выделил необходимым минимум и сконцентрировался на нём, в то время как Вася говнокодил без плана в голове.

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

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

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

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

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

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

PS: TDD в этой статье под словом «рефакторинг», потому что рефакторинг по Фаулеру, это всегда тесты, тесты, тесты и только потом действия.
Про тесты. Я считаю, критические места должны быть покрыты тестами (отправка заказа, логи платежей и тд), а на каждый чих тест на первом этапе не нужен — YAGNI. Но не всегда это возможно.
Если говорить в контексте TDD, тесты покрываются кодом, а не код — тестами.
У меня почему другие мысли в голове.

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

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

А что про статью, то:
Сразу скажу — не моя идея, в статье «Проектирования больше нет?» сам Мартин Фаулер писал об эволюционном рефакторинге.

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

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

Добавлять новую функциональность надо сначала в отдельной ветке, и после этого переписать так, чтобы вписывалось в основной код.
Затем мы делаем сводный отчет за час руками в php
Я тоже раньше так делал, а потом открыл для себя сводные таблицы в Excel! На удивление «GROUP BY» в сводных таблицах в Excel во многих случаях работает даже быстрее, чем в MySQL.
Что делать, если результат надо отдать конечному пользователю на web-странице?
Ты не поверишь, но есть прекрасные средства, которые это реализуют. Excel Services в SharePoint например.
Речь была о PHP.
Но допустим, платформу мы вправе выбирать.
Ставим заказчику Sharepoint и заставляем купить?
Ставим заказчику office365 за 500 рублей в месяц. Это примерно один день работы программиста. Что даже за несколько лет выгоднее чем поддерживать код.
Всё там не так просто…
A WCF endpoint is required

По-любому, поддержка программиста будет нужна. И более квалифицированная, чем потребует наговнокоженный php-генератор, сосущий данные из MySQL
Есть rest интерфейс для вытягивания диаграмм и данных. Поддержка программиста нужна чтобы урл написать один раз.
Я не про вывод результата, а про ввод данных в генератор отчёта
И второй вопрос: 500 руб — это на аккаунт?
Т.е. заказчик должен авторизоваться как в нашем приложении, так на Office365, а если такой отчёт нужен как страница для клиентов, их тоже в этот аккаунт офиса пускать?
Нет, приложение на PHP получает данные из excel на SharePoint. Для этого лицензии не нужны. Дальше они как есть передаются во view. Диаграммы из excel можно прямо картинкой забирать. Если нужно отфильтровать по клиенту, то можно это сделать на стороне приложения.
Кажется, при такой архитектуре Office365 тут как собаке пятая нога (ну или похоже на попытку впарить сервисы микрософт).

Получается, надо писать
1. wcf-endpoint, выкачивающий данные из SQL (который тоже надо поддерживать, т.к. все варианты join-ов сразу не предусмотришь, а join-нить в excel через xLOOKUP медленно) — обязательно на Windows Server + IIS, никто больше WCF не захостит
2. excel-файл в облаке MS, подключенный к источнику данных и содержащий сводную таблицу, который надо поддерживать при изменения отчёта
3. оплачивать аккаунт Office365 и следить на его конфигурацией (URL-ы подключений)
4. иметь веб часть на PHP (теперь уж поставили IIS в шаге 1, можно и ASP), которая из облака по REST вытянет данные из excel и представит в html-виде

и всё это вместо простейшего php/asp-скрипта, который по ADO подключится к базе, сделает SQL-запрос и выплюнет результат в HTML-таблицу
ОМГ зачем это все? Excel умеет втягивать данные из любого ODBC-совместимого источника. Никаких WCF, IIS не нужно.
Одним GET запросом можно забрать данные из Excel на стороне PHP, еще два запроса нужны для авторизации.

Недостаток — обновлять данные надо ручками (макросом, скриптом на VBS), o365 не умеет сам обновлять внешние данные в excel, только в on-premise варианте.

Это все имеет смысл если расчеты сложнее одной функции агрегации, типа sum или avg. Я знаю проекты, которые на таком ad-hoc решении прожили довольно долго.
Речь о десктопном excel или web-excel в office365?
Создать таблицы в десктопном excel, положить на портал, тянуть данные через веб.
Допустим, обновление документа на сервере из ODBC-источника возможно (Хотя сомневаюсь — обычный сценарий работы с ШП — юзер открывает документ в обычном excel и обновляет из ODBC-источников, которые настроены у него в системе локально, используя свои логины-пароли подключений к БД, затем сохраняет документ обратно)

Но безопасно ли открывать свою БД наружу в интернет?
Ограничение прав пользователя в базе + Надежный пароль + SSL (если БД поддерживает), почему нет?

При использовании excel services как раз не надо давать пользователям сам документ, только данные \диаграммы из него. В onpremise можно настроить обновление на сервере, без открытия самого документа.
1. есть риски, что базу тупо задосят (http-серверы давно на публике и более-менее умеют противостоять, в отличие от sql)

2. on-premise это другой ценовой сегмент. аргумент «500 руб в месяц» не прокатывает
Пару раз так сделаем и всё оставшееся время будем решать проблемы деплоя и интеграции.
А мой заказчик раньше делал отчеты в сводных таблицах Эксель, а потом попросил меня написать аналог на PHP. В Экселе ему приходилось делать слишком много лишних движений, а он хотел чтобы все было по одному клику.
Как вам не стыдно. Надо было показать ему, как записывается макрос в Excel.
Тогда уточню. Раньше они делали отчеты врнучную для своих клиентов. А сейчас они хотят чтобы клиенты сами могли заказывать отчеты через веб интерфейс в режиме онлайн. Система написана на PHP.

А генерация сводных отчетов на PHP из базы данных — на самом деле достаточно простая (не дорогая) задача. Делаем выборку из БД, крутим циклы, добавляем значения в матрицу. Потом пересчитываем ячейки этой матрицы.

Но про макросы в Эксель, это вы правильно подметили. В некоторых ситуациях это замечательно.
В статье «стартап-ловушка» говорится о том что нужно «Do right things» даже в стартапе. Двигаясь в неверном направлении невозможно достигнуть успеха. Невозможно получить качественный продукт, постоянно экономя на качестве. Правда фокус чересчур программерский.

В этой статье написано о том как «Do things right». О том что эволюция прототипов эффективнее, чем Big Design Upfront. О том что частые релизы, важнее вылизывания.

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

Как пример, нам достался проект считалки хайлоад. Разработчики там хранили уникальные айди юзеров как комбинацию куки и еще других вещей хз где, а потом для повышения производительности «отрефакторили», что записываться айди стал в мемкешд. А че, типа быстро работает. То, что такое ACID и что мемкешд стирает ключи в процессе работы — ну не бд это, как, видимо, думали — это не про наших парней.

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

И таких примеров море. Эффект Даннига-Крюгера в действии
Писать надо не криво, а минимально реализуя функционал. То есть KISS. Это и есть основополагающий принцип для «Do things right».

Про считалку — отказ от durable хранилища противоречит «Do right things».

Причем тут эффект Даннига-Крюгера не понял.
Согласен.

Но часто это в целях скорости близкие вещи. Сто классов и сто тестов против одного класса — уже разница во времени.
Если вы думаете, это шутка, то не видели проекты, где на каждый чих новый класс, два интерфейса и тесты уровня «умножает ли оно дважды два». Потому что чем больше про изменения говоришь, тем больше программист через ООП старается себя обезопасить. И убедить написать говнокодом можно, только пообещав дать время отрефакторить

Эффект при том, что люди считали себя умнее, чем на самом деле, и уверенность в своем уме и уровне ослепляет, что ведет к ошибкам
Золотые слова!
Невозможно получить качественный продукт, постоянно экономя на качестве
Пока вы делаете качественный 3 года, конкуренты сделали «средненько» за год. Да много недовольных, но паровоз уже поехал. Через 3 года вы закончите первую итерацию, а ваш конкурент, делавший «ширпотреб» прошел уже 3 итерации, и бабок нарубил и клиента лучше понимает.

Вот если вы выходите на более-менее стабильный рынок со стратегией «порвать конкурентов качеством» тогда да. Только так.
Начнем сначала, чтобы были «on the same page». Есть стратегия обеспечения качества, описанная во множестве методологий. Например для кода: проведение ревью, тестирование, устранение ошибок перед разработкой нового функционала. Для интерфейса: проработка сценариев использования, usability тестирование. И так далее.

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

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

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

Все хорошо в меру, и говнокод, и рефакторинг.
Автор не указал главного: если система написана модульно (на примере XAML — каждый блок интерфейса вынесен в user-control, имеет понятный интерфейс и простой код для связи этих блоков), то легко экспериментировать, перетасовывая блоки и подкручивая их параметры.

Если всё написано одним большим блоком говнокода, чтобы перенести поле ввода на 30 пикселей выше и ничего не поломать, надо час времени.
Это будет сильно сдерживать эволюцию проекта, программеры будут сопротивляться внесению изменений.
Да, модульность крутая тема. Но иногда бывает, не знаешь, какие модули завтра будешь делить, какие объединять. Поэтому декомпозицию ИМХО стоит делать после пары итерации уже, когда ясно, что сделали нужное. А то начали соцсеть, пришли к инет-магазину, потому что остальное юзерам, кроме товаров, бывших одним из 10 разделов, нафиг не уперлось.
Как раз этот пример скорее в пользу модульности изначально — делали соц. сеть, при этом каждый кусок функционала был реализован в отдельном модуле: пользователи+авторизация отедльно, социальность отдельно, магазин отдельно, еще 9 разделов в 9 отдельных модулях.

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

А если все изначально в одном месиве написать — где нельзя разобрать где начинается магазин и заканчивает лента друзей — то тогда потребуется итерация только на то что бы вытащить функционал инет-магазина.

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

Иначе получется ситуация: «Пока можно говнокодить… все еще можно… еще немного поговнокодим… Ааааа… Покатился снежный ком говнокода и похоронил проект.»
НЛО прилетело и опубликовало эту надпись здесь
Роберт опытен и многое предвидит.

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

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

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

А лучший способ влезть в шкуру клиента и понять его задачи — дать ему пластелин, чтобы он сваял макет. А потом вы ему из золота (чуть не написал «гранита») отольете его протип.

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

Я еще скажу, если разработчики заведомо видят, что задача обречена на провал, то у них самих возникает обида за вероятно потраченное в пустую время и соответственно понижается мотивация.
У меня в таких ситуациях возникает желание как раз писать «идеальный» код. Хоть к резюме можно будет приложить :)
Кстати да =) Можно.
Так что на сотой итерации должен быть крутой код

Если его нет, вопрос qa
Количество костылей растет когда с самого начала есть попытки создать «идеальную архитектуру». Простой и прямолинейный код легко менять, легко перемещать и легко развивать. Как только появляются паттерны резко код перестает быть простым и любое изменение, не укладывающееся в «идеальную» архитектуру, производит костыль. Потом применяется «паттерн» чтобы исправить костыль, но со временем это порождает еще больше костылей.
мегасвязанный zend, когда ООП ради ООП, и на простые операции 100500 вызовов функций плюс сверхвысокая связанность
Автор покусился на священную корову Zend Frameword, критиковать которую, во многих кругах считается опастной ересью. Но я с автором полностью согласен.
Говорят, он стал лучше.

Но чем прет Симфони — бери и юзай отдельные куски. Философия Юникс в действии. SOLID, low coupling, high cohesion — все давно известно.

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

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

Мне, почему-то, всегда казалось, что просто кодить, пусть и качественно, не поднимая головы и не интересуясь о чем думают коллеги, ПМ, QA и даже заказчик, — это крайне безответственно.
По-моему, безответственно это, только если совмещаешь несколько или даже все роли. А если ты именно разработчик, то, ты не то что не должен, а просто не имеешь права принимать решения, сильно и неоднозначно влияющие на экономическую эффективность, в частности на баланс между сроками (и стоимостью) разработки и поддержки, в том числе писать «говнокод» или использовать «лучшие практики». Просто это не твоя зона ответственности, даже сли считаешь, что ты компетентен. Минимальные требования к качеству кода и максимальные к сроку должны быть тобой получены от того, кто несет ответственность за эффективность решения бизнес-задачи. Можешь сделать быстрее, не уменьшая качество — ради бога. Можешь сделать качественнее, не выходя за сроки — тоже хорошо. Но вот делать менее качественно или более долго не имеешь права. Максимум можешь выступить с предложением «давайте качество будет похуже, но сроки сократятся на порядок» или «давайте срок увеличим в 1,5 раза, но качество будет выше на порядок».

А вообще «говнокод» и «лишь бы работало» не синонимы. Вполне можно минимальными усилиями значительно поднять качество кода при его создании или по горячим следам, пока технический долг не начал обрастать процентами (говнокод заработал — потратил 5 минут на небольшой рефакторинг, хотя бы этот говнокод изолируя и создавая ему контракт/интерфейс, пускай неоптимальный, но явный), особенно с современными IDE, которые многую рутинную работу по созданию и изменению интерфейсов могут автоматизировать.
Так я нигде и не писал, что разработчик должен принимать такие решения в одиночку. Не должен, разумеется. Но там, где «стандартный» разработчик потратит неделю, допустим, на реализацию change request'а, я потрачу денек потому что задумался каковы реальные цели заказчика и предложил измененную версию его запроса, которая будет удовлетворять его цели и, одновременно, будет стоить нам куда как меньше времени. Цифры, конечно, взяты с потолка.
Имхо, сначала предложить, а уж потом день тратить. И в ожидании ответа на предложение работать либо над задачей сне меньшим приоритетом (если зависимости и общий дедлайн позволяют), либо над текущей в первоначальной формулировке. В общем чтобы у проекта в целом не было задержек, если новую формулировку задачи не примут.
Хорошая статья и обсуждение в комментах)
В текущем проекте после того как была «сформирована» архитектура, потом переформирована и снова и снова. Пришел к мысли о «проектировании через эксперимент». Когда важные архитектурные изменения, но не фундаментальные, вносятся в соответствии с реальными требованиями и поведением пользователей и системы под их воздействием.
Я обычно пишу так: быстренько пишем рабочий код под задачу, и рефакторим по мере необходимости, но делать это я стараюсь заблаговременно, т.е. если вижу что в дальнейшем расширение функционала может споткнуться о текущую реализацию, при появлении времени делаю рефакторинг. Так же иногда быстро пишешь говнокод чтобы проверить идею, затем рефакторишь. Правда программирование для меня это больше хобби.
Так всегда и бывает, у хорошего программиста всегда идет background refactoring.
Почему-то часто встречаю альтернативы — сделать «неправильно и быстро» или «правильно и долго». На практике же это часто выглядит как сделать «неправильно и долго» или «правильно и быстро».

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

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

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

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

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

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

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

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

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

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

Пример — циан.ру
Долгое время был плохой дизайн, но проект решал задачи. Деньги шли, квартиры добавлялись. А потом наняли Лебедева отрефакторить дизайн.

Это трудно сразу принять, меня год учили этому хорошие учителя, спасибо им.
Мне кажется, вы про одно и то же пишете :) Что сначала надо подумать и максимально использовать известные факты, а когда появятся новые — подумать ещё раз.
Нужно правильно представлять себе задачу, которую решаешь. И писать код соответственно. Не нужно ни переоценивать ее, ни недооцнивать.

Даже в случае прототипа нужно написать достаточно хорший код, чтобы иметь возможность закончить его до коллапса архитектуры. Если вы не сможете зарелизить проект, то и обратную связь не получите, ведь так?
Работающий код — это самое первое требование, конечно
работающий код — понятие относительное, а не абсолютное.
если код работает в 3 случаях из 5 — все согласятся что это говнокод (но если все-таки иногда работает — значит еще не совсем треш)
если гипотетичести существует (но практически встречается раз в 100 лет) ситуация, когда код падает — это ведь тоже не идеальный код? но стоит ли всерьез рассматривать такую ситуацию?
где же проходит граница между «работающим» и «неработающим» кодом?
Почему-то часто встречаю альтернативы — сделать «неправильно и быстро» или «правильно и долго». На практике же это часто выглядит как сделать «неправильно и долго» или «правильно и быстро».

Такое бывает, когда в команде есть принципы, из-за которых кода пишется больше, а это делать лениво.

Например, все модули должны стыковаться через Dependency Injection. Но кто-то заленился объявлять интерфейс, регистрировать его в контейнере и вызвал напрямую. В итоге получилось быстрее, но хуже тестируется.

Ещё пример: вместо того, чтобы разобраться с какой-то тонкостью ORM, пишем прямой SQL. Сиюминутно быстрее, в будущем сложнее рефыакторить

Другой пример. Принято использовать паттерн MVVM, но вот что-то не придумывается сходу, как через binding сделать. Надо гуглить, думать или читать исходники компонента. Вместо этого пишется небольшой костыль, выполняющий бизнес логику не в Presenter, а во View. Проблема решена, закоммитили, забыли. Затем этот Presenter подсунули другому View — костыль придётся копипастить.
В итоге получилось быстрее, но хуже тестируется.
Вы же не забыли прибавить время отлова багов в условиях отсутствия теста ко времени разработки?

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

И вот если все это посчитать, то может оказаться, что в итоге-то вышло дольше.
Большая вероятность, что непротестированный модуль править не будут. А второй View у этого Presenter-а не появится.
Особенно эта вероятность велика, если прототипу жить недолго до очередного большого изменения требований, которое вызовет серьёзное переписывание и выкидывание этого кода.
И вот если все это посчитать, то может оказаться, что в итоге-то вышло дольше.

Иногда дольше — это лучше.

Вариант 1: написали вообще без тестов, кое-как запустили, получили финансирование. говнокодим дальше.
Вариант 2: не уложились по срокам, проект закрыт.
Все ваши примеры применимы, когда между событиями «начали писать» и «закончили писать» есть такой чекпоинт, как релиз, в результате которого все может поменяться.
Событие «закончили писать» как правило не наступает после первого релиза ))
говнокод может быть приемлем только там, где он может быть локализован


+100. Один из способов я предлагал в прошлом топике. Пускай не покрывать код тестами, но писать его имея тесты в ввидую Постоянно думать «как я это буду тестировать»…
У конкурентов начинается срач между ведущими, которым жалко менять спроектированное меню и две недели крутого правильного программирования, плюс у них замылен глаз. В итоге мы получили две недели времени.

А что было бы, если бы в этой конкретной ситуации трехуровневое меню оказалось правильным выбором?

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

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

С другой стороны, возьмем простую арифметику. Создать меню в HTML — пусть час работы. Добавить туда новый пункт — минут 10 (с учетом всех сопутствующих процедур, в виде проверки, добавления в репозиторий и прочего...). Написать универсальное меню — пусть 40 часов. На него ведь завязано очень много всего. Вопрос, сколько изменений можно вносить руками, чтобы это наконец стало затратным? Ответ: 234. Этого на всю жизнь данной версии сайта может хватить. Побеждает не тот, кто сделал правильно, а кто предоставил решение потребителям раньше всех.
Универсальное меню можно таскать из проекта в проект.
Можно конечно же. А нужно?

Приведу несколько примеров из собственной жизни. В процессе разработки проекта применялось три подхода:
  • Тупняк в виде меню в HTML
  • Чуть менее тупо. Структура хранилась в файлике, выводилась универсальным темплейтом, в том числе с учетом прав
  • Универсальное меню, полное управление с UI


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

Два момента:

1. Это только кажется «10 минут». Вы отвлекаете программиста, выводите из контекста. Потом он пойдет пить кофе, т.к. не сможет сосредоточиться.

2. Хороший архитектор это не тот, кто делает сам каждый кирпичик. Вполне можно не клепать самим HTML-меню а купить готовое. Я однажды пришел к выводу, что делать контрол под проект — практически всегда плохая идея. Хорошее меню — уже отдельный проект на несколько месяцев работы.
1. Я в эти 10 минут включил и смену потока. Скопировать одну строчку и поменять два значения в новой строчке не занимает более 1й минуты работы

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

1. Я в эти 10 минут включил и смену потока. Скопировать одну строчку и поменять два значения в новой строчке не занимает более 1й минуты работы

Для правильных языков (.Net, Java) вы сначала достаете из репозитория нужну ветку (1-2 мин.), открываете проект в студии (до 5 мин, если большой проект), находите эту страницу, исправляете (1-2 мин.), компилите, запускаете, проверяте что все работает (до 5 мин.), коммитите изменения в репозиторий (1-2 мин.), деплоите новую версию на сервер (если вы имеете права — 1-2 мин., при этом сайт будет не доступен.).

Итого, для сайта на .Net (на Java будет то же самое) — от 14 до 18 минут только изменение, без учета смены контекста.
<styob_mode>Зачем такие дорогие технологии используете? :) </styob_mode>
Зачем такие дорогие технологии используете? :)

Ну а почему одни люди носят обувь за $300-500, а другие дороже $20-50 ничего в жизни не обували?

Это высший класс. Да, технологии дорогие, но есть люди, которые не гонятся за дешивизной. И мне приятнее работать с такими людьми.
… точнее — зачем использовать такие дорогие технологии с таким дешевым железом, что проект открывается до пяти минут?
А причем тут железо? Вы NuGet используете? Репозиторий пакетов используете? Сколько зависимостей в вашем проекте?
NuGet и репозиторий пакетов не влияют на время открытия.

Ну и да, не важно, сколько зависимостей, проект не должен открываться столько времени, это непродуктивная трата времени разработчика. SSD и память нынче недороги.
А вы NuGet используете только для внешних библиотек, или и для своих? У вас есть свой (внутренний) репозиторий-NuGet для пакетов, или храните их вместе с исходниками?
Пакеты хранятся в версионнике (чтобы гарантировать стабильность). Соответственно, сколько их, уже не важно.
Классическим решением является свой NuGet-репозиторий. При первом запуске происходит авторизация и скачиваются пакеты (с учетом всех зависимостей). Потеря 2-3 минут единоразово не критична.

Можно хранить пакеты и с исходным кодом — есть плюсы и минусы такого решения. В таком случае у вас уйдет больше времени на постоянное обновление папки с пакетами (в итоге может даже больше потеряете).
Классическим решением является свой NuGet-репозиторий.

Вы про это «классическое» решение расскажите Хамблу/Фарли, хорошо?

Потеря 2-3 минут единоразово не критична.

То-то вы выше на это жалуетесь, да.
То-то вы выше на это жалуетесь, да.

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

А вот в вашем проекте сколько времени уйдет на передеплой старой версии с мелким изменением и ручным тестированием?
А вот в вашем проекте сколько времени уйдет на передеплой старой версии с мелким изменением и ручным тестированием?

А почему такой упор на ручное тестирование?

А вообще — в пределах 15 минут, из которых 10 — это пречекин и деплой. И это время, вкупе с забором версии, как раз уходит на вход-выход из контекста.
А вообще — в пределах 15 минут, из которых 10 — это пречекин и деплой

Ну вот видите: 10 минут. Никак ни одна минута :)

По переключению контекста за 2.5 минуты — мне до вас далеко (у меня уйдет минут 20-30). Я пишу код в измененном состоянии сознания, в своего рода трансе. Могу и просто писать, но эффективность во много раз ниже.
Ну вот видите: 10 минут. Никак ни одна минута

А я и не утверждал, что одна минута. Но по факту, как раз в 15 минут можно уложить правку и смену контекста.

Я пишу код в измененном состоянии сознания, в своего рода трансе. Могу и просто писать, но эффективность во много раз ниже.

Могу вам только посочувствовать.
А я и не утверждал, что одна минута. Но по факту, как раз в 15 минут можно уложить правку и смену контекста.

Утверждал s0rr0w. У него получилось 1 мин. + 9 мин. на переключение. А у вас 10 мин. + 5 мин. на переключение. У вас сшилком быстро происходит переключение контекста, у большниства программистов займет значительно больше 5 минут.
Я для себя вывел формулу: не более 5 переключений в день. Кстати, многие с кем обсуждал — согласились и даже приводили в подтверждение некие исследования.
А у вас 10 мин. + 5 мин. на переключение.

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

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

Может быть, это повод работать над собой?

Я для себя вывел формулу: не более 5 переключений в день.

Сочувствую вам. У меня переключений контекста в день десятки.
Сочувствую вам. У меня переключений контекста в день десятки.

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

А так — Embrace Interruptions.
что человек реально за рабочий день не больше пяти раз отрывается от работы на что угодно

Правильно.

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

Зависит от работы. Если работа сложная — бывало и на несколько дней забывал про форумы и хабры. Скайп специально отключал.

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

В среднем случае (не очень сложная работа) неожиданное срочное задание минут 30 оттягивает.
Я могу повторить еще раз: я таких никогда не видел.
Я могу повторить еще раз: я таких никогда не видел.

Эффект избирательности. Даже если увидите — не поверите, будете думать что человек мухлюет :)
Почитайте статью, посмотрите обсуждение. Сколько в среднем в день ваши коллеги решают задач (посмотрите выписку из Jira). Везде увидите это магическое число 5-7, даже если задачи мелкие.
И не ставьте знак равенства между отвлечением на просмотр новостей/статей и выполнением работы.
Почему же, поверю. Если и когда увижу.

Сколько в среднем в день ваши коллеги решают задач (посмотрите выписку из Jira)

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

И не ставьте знак равенства между отвлечением на просмотр новостей/статей и выполнением работы.

А вот это как раз неверно. Потому что смена контекста-то происходит, просто вы отказываетесь ее признавать.
А вот это как раз неверно. Потому что смена контекста-то происходит, просто вы отказываетесь ее признавать.

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

Просмотр новостей/статей — не отдых. И, самое главное, рутинная работа («добавить строчку в меню»), ничем не отличается от чтения статей на хабре по нагрузке на мозг, и, если является плановой задачей, точно так же активируется вами. Так что нет никакой разницы по стоимости смены контекста.
Просмотр новостей/статей — не отдых.

Здесь градация. Не да/нет, а множество оттенков. Кроме того, зависит от вашего отношения к новостям: если вы биржевый трейдер, то для вас это действительно не отдых.

рутинная работа («добавить строчку в меню»), ничем не отличается от чтения статей на хабре по нагрузке на мозг

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

Мой же критерий доверия остается очень простым и прямолинейным.
В итоге ваше «правило» обрастает таким количеством оговорок, что в практической жизни становится неприменимо.

Ну… Психология не точная наука.

Мой же критерий доверия остается очень простым и прямолинейным.

Какого доверия?

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

Это нужно провести соц. опрос в среде программистов.
Соцопрос бессмысленнен, потому что опирается на внутреннее предубеждение.

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

А почему вы считаете что оно ошибочно? Есть причина так считать?
Потому что мнение человека о том, как ему комфортнее работать, основанное только на предубеждении, может быть корректным, а может и не быть корректным. Нельзя сравнивать вещи, которые ты не пробовал.

Что характерно, именно на этом основывается обучение: вы сначала научитесь, как правильно, а потом будете говорить, что вам так неудобно… если все еще будет неудобно.
Я могу повторить еще раз: я таких никогда не видел.
Бывает, исправил одну строчку и не можешь о ней забыть 30 минут.
Думаешь: а всё ли правильно сделал, а учёл ли все граничные случаи. Иногда бывает, что при прокручивании в голове недавно правленного кода находишь баг где-то рядом, возвращаешься и доделываешь.
Автор почему то считает, что невозможно писать быстро и в тоже время без «говнокода». И кстати это будет быстрее и проще. Говнокод — это не панацея быстрого результата
Автор, Мартин и Фаулер пишут о том, что следую принципам KISS и YAGNI, необходимо выбирать самый простые алгоритмы и решения, удовлетворяющие текущим требованиям. А использование TDD позволить в дальнейшем, когда требования изменятся и усложнятся, безболезненно внедрять более сложные архитектурные решения а алгоритмы.

А вот о том, что простой код — это говнокод, и тем более, что говнокод обязателен, они точно не пишут, не стоит вводить читателей в заблуждение ;)
Опечатки не успел поправить :)
Почему-то всегда подразумевается, что делать хорошо — значит делать долго. Говнокод дает выигрыш в скорости разработки только очень маленьких проектов. А хороший код почти сразу начинает давать свои плоды, заметно снижая время на расширение и внесение изменений в проект.
Полностью разделяю вашу точку зрения. Как то посвятил месяц на скелет фреймворка для внутреннего пользования, делая его модульным, легко расширяемым, необходимые хелперы, возможность переопределения любых частей модуля (контроллер, модели, вьюхи,js-lib,conf), написал базовые модули и прочие удобные вещи для себя. В результате сейчас при необходимости добавить новую фичу или даже большой модуль и т.д. времени уходит меньше чем писать тоже самое самым жестким хардкодом)
Говнокод — это как мина в поле — обезвреживание в десятки-сотни раз дороже ее установки. И стратегия «throw over the wall» — не работает. У нас на проекте предшественники в базовом модуле накрутили какашек для «ускорения» процесса, и это дало метастазы во все остальные модули. В итоге построили высотку на гнилом фундаменте. И теперь чтобы все переписать и заменить на вменяемый код потребуется не один пресловутый человеко-месяц. И процесс разработки на этом проекте примерно такой: 2-3 дня разбираешься в говнокоде, пытаясь понять, что же он должен был делать, и в надеждах что его можно спасти рефакторингом, потом понимаешь что это никогда не работало и работать не могло и за 1-2 дня все переписывается с нуля. В итоге, колоссальные потери времени на самых простых фичах.
Самое смешное, что легко называть чужой код говнокодом.
Так же после вас придёт поколение поддерживать, что вы написали, и так же будет плеваться: «наговнокодили, а нам теперь всё переписывать и рефакторить» ))
По этому поводу есть объективный критерий: image
Количество WTF сильно зависит от знакомства того, кто читает код, с приемами и шаблонами того, кто его писал. Если разработчик и ревьвер представители одной, так сказать, школы, то количество будет минимальным, хоть в случае спагетти, хоть в случае перенасыщения ООП- и архитектурными патернами.
Прежде чем проводить ревью, нужно ознакомиться со стилевыми и архитектурными правилами, принятыми в проекте. Тогда многие вкусовые WTF отпадут сами собой.
Явно сформулированных их может и не быть.
Я бы тогда с них начал)
Усиливать связанность и ослаблять связность проще чем ослаблять связанность и усиливать связность :)
В реальной жизни в 99% случаев будет так

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

Если серьъёзно, то все эти споры всегда упускают одну важную деталь — О каких приложениях идёт речь? Сложность и ответственность являются определяющими. Если вы пишите никому не нужный пет-стартап с картинками и котиками то волне подходит говнокод как вариант времяпрепровождения. И никакого рефакторинга там никогда не понадобится, кстати. Если же вы взяли у бандитов десять миллионов долларов и пишите подпольное казино или взяли у государства миллиард и пишите почту России то подход должен быть с большим колличеством метрик.
Эх, если бы «владельцы» госпроектов относились к ним как многие стартаперы к своим, никому ненужным проектам…
взяли у государства миллиард и пишите почту России то подход должен быть с большим колличеством метрик.

Скажите честно, вам приходилось работать с госструктурами? (я про РФ, конечно)
В php примером является ранний мегасвязанный zend, когда ООП ради ООП


не совсем понятно, что в зенде имеется ввиду под многосвязаностью, и как это относится к ООП ради ООП. Можно поподробнее?

Зенд всегда был набором библиотек натыреныхпортированных с других фреймворков, поэтому они все были разрозненные и обязку для них нужно было писать самому ручками. К примеру, ACL вобще ничего не знал по MVC, также как и AMF, REST, Tool. На вскидку, могу вспомнить Date, Config, View на которых были зависимости в других компонентах, все остальное нужно прикручивать самому.

В симфони все немножко не так, он более монолитен и все компоненты подогнаны друг под друга, ручками писать, практически, ничего не нужно.
Почему никто не вспомнил про такое слово как — Agile!? Ведь описанное в топике пересекается с принципами этой методологии. На каждую итерацию разработки берём самые важные и ценные пользовательские истории (фичи, желания, требования, хотелки, фидбеки) и разрабатываем только их, получая результаты в кратчайшие сроки. И так с каждой итерацией, быстро реагируя на изменения пользовательских историй, дорабатываем только то, что оказалось востребованным, и выкидываем то, что оказалось не востребованным и разрабатывая фичи под новые пользовательские истории.

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

Нельзя разумно допускать ошибок, которые характерны малой квалификации, опытности или незнанию азов, теории и правил поведении при определённых используемых программных средств и языков программирования, правил, принятых на проекте и вообще в команде — если при этом ты знаешь, что это будет ошибкой такого уровня. Если увидел такие ошибки в чужом коде — укажи на них его автору, минимальными усилиями поправьте и продолжайте работу.
По-моему, речь о возможности по разному писать код в пределах каждой итерации. Допустим решили сделать в текущей простое плоское меню на HTML, только навскидку 5 вариантов:
— жесткий хардкод в шаблоне. Максимум урлы хелперами генерируются. Добавить пункт меню — нужно ручками в исходниках писать теги li, а, может img и т. п.
— какой-то захардкоженный массив, который в шаблоне циклом выводится. Добавить пункт — элемент в исходниках в массив добавить, возможно перекомпилировать, в любом случае деплоить
— то же, но файлик или таблица в БД, откуда массив заполняется. добавить пункт — файлик отредактировать или табличку, в исходники лезть не нужно
— то же, но есть полноценная админка
— автоматически формируемое меню на основе списка подключенных модулей, к каждому модулю добавляется метаинформация о его отображении в меню или для отображения используется существующая метаинформация.

При этом ещё любой пункт может быть сделан качественно (покрыт тестами, задокументирован, тщательно подобраны имена сущностей, отмечены будущие возможные todo и т. п.), а может быть сделан по принципу «лишь бы работало» (тестов нет, документации нет, имена типа a1, a2 и т. п.), а может только частично за качеством следили. В общем вариантов масса и какой из них счесть «минимально необходимым» напрямую к Agile не относится, это вопрос QA.
Кстати, в подобного рода публикациях почему-то никогда не упоминается квалификация разработчиков, а это не последний фактор, влияющий на качество кода. Квалифицированный, опытный программист никогда не опустится до уровня говнокода просто потому, что не сможет. А неопытный или попросту ленивый всегда найдет отговорку (сроки, прототип, дедлайн), призванную оправдать низкую квалификацию. При этом стоимость разработки будет идентична, а вот в стоимости поддержки выиграет хороший (не путать с идеальным) код — это очевидно.

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

Тем не менее, можно идти и вашим путем, если запланировать полный рефакторинг (читай — переписать с нуля) с версии 2.0. Новая архитектура будет разработана с учетом опыта и потребностей реально работающей системы.
Но снова таки без учета будущих требований. Пока вы пишите вторую версию, бизнес не стоит на месте, и вполне возможно, что вы еще не дописали, а уже нужно снова рефакторить. А еще старую систему поддерживать надо. У меня была такая ситуация. Пришлось на конкретном примере показать, что про старую систему лучше всего забыть, иначе новая никогда не будет написана.
Я думаю, тут речь о рельсах под технологиями, а не под поведением и бизнес-требованиями.
Например, сразу используем трехзвенку, а не двух. Или сразу берём мощный генератор отчётов, а не собираем на коленке.
Рефакторинг нужно проводить непрерывно. Три недели разрабатываем, неделю рефакторим — это не самый удачный подход. Удачный — сделали фичу (задачу), отрефакторили тесты, отрефакторили код. Время на рефакторинг закладывается при оценке задачи, точно так же, как и время на написание тестов.
Ну а рефакторинг легаси кода — это отдельная история. Фаулер рекомендует сначала покрыть код функциональными тестами, чтоб зафиксировать поведение, и только потом приступать к рефакторингу. Такая задача, действительно, может потребовать серьезных затрат.
Модельный пример довольно однобокий и больше касается не написания кода, а стратегий приложения усилий что бы опредить конкурентов. Но в долгосрочной перспективе вполне может быть конкурент который знает как правильно, и будет писать это правильно месяц. Через месяц выкатывает — вы умираете или выкидываете текущий говнокод что бы переписать на новый «правильный» лад.
В общем тут все зависит от стоимости кода. Если его можно переписать за неделю. И это может сделать любой программист с улицы — отлично.
Если этот код написал некий «математик» и никто не можешь его даже прочитать — то другое.
А статья скорее о том что модель\прототип надо иметь как можно раньше, и как можно раньше начинать тестировать на пользователях, особенно если это массовый продукт, такой как сайт.
Конечно все мое _имхо_.
Еще ни разу я не видел, чтобы говнокод приносил пользу, наоборот: саппорт, фиксы, миграции на новый фреймворк/платформу — все проходит очень болезненно, а некоторые вещи просто невозможны. Авторы говнокода к этому моменту обычно говнокодят что-то новое или уходят (они ведь сделали свое дело), фикс говнокодером говнокода является говнокодом в квадрате и скорее всего не будет сделан вовремя. Не нужно писать совершенный код, среднего и не очень хорошего качества достаточно, чтобы сильно облегчить себе и другим людям жизнь.
Все зависит от точки зрения, что именно считать говнокодом. Для меня говнокод это не тот код, который написан в спагетти-стиле, а тот, который не решает поставленную задачу. Я видел немало людей, которые увидев тот подход, который мы используем, и тот код, который мы пишем, говорили одну фразу: «Что за говно?». Зато я точно уверен, что с поставленной задачей мы справляемся на ура.
Просто частенько бывает, что не все задачи стоящие перед кодом заказчиком озвучиваются или вообще имеются в виду. А потом всплывают. Скажем, когда взял другого исполнителя на модификацию.
Заказчик часто что-то не договаривает, путается в показаниях, не смотрит дальше своего носа, и, зачастую, описывает проблематику полугодичной давности. Вот тут в игру должен вструпать архитектор, который предвидит проблемы до того, как они возникнут. Другими словами, архитектура приложения должна в первую очередь учитывать будущие модификации. Единственный способ это сделать, который мне известен, это конфигураторы и конструкторы. Т.е сначала пишется конструктор, а потом уже на нем выполняется основная задача.
Далеко не каждый заказчик согласен будет заплатить за разработку конфигуратора или конструктора. А если разбивать стоимость на нескольких заказчиков (грубо говоря, сделать коробочный продукт), то это уже другая бизнес-модель, по-моему. Не разработка софта на заказ, а продажа конфигуратора и услуг по конфигурации.
Открою большой секрет. Только никому, ладно?

Есть технологии, благодаря которым конструкторы можно создавать невероятно быстро. Например XML.
Я за два дня написал то, что продается другими компаниями банкам за сотни тысяч долларов :)

Если вернуться к нашим беседам чуть раньше, я приводил пример шаблонизатора на XML, который можно написать за неделю (базис пару дней пишется). Это не тот срок, который может серьезно пошатнуть финансовое благополучие заказчика.
Как я понимаю, XML в таком случае лишь формат хранения конфига. Его обработку все равно нужно будет писать. И по сути не важно как хранится конфиг — XML, YAML, JSON, INI, в БД, захардкожен с выносом в массив/объект или вообще прямо в коде. То есть по идее то, что вы написали я бы мог написать «в лоб» условно за день.

Шаблонизатор весьма частный случай, шаблон описывает представление данных в разных форматах, но он не может описывать логику их обработки. Или это уже будет не шаблонизатор,, а второй PHP :)

В общем я с трудом представляюю себе конфигуратор для достаточно широкого круга задач (как бизнес, так и технических), без того чтобы язык его конфигурирования не перерос в язык программирования (пускай не символьный, а графический) со всеми вытекающими. Что-то узкоспециализированное — вполне. А реализовать произвольную логику — нет.
Задача конструктора — решать маленький спектр задач наилучшим способом. Приведу еще один пример, где это работает в полную силу. В современных x86 процессорах сложные макрооперации (CISC) транслируются в микрооперации (RISC). Потому что так проще всего перестраивать их и наиболее эффективно использовать исполнительные устройства. Такая технология как Hyper Threading была бы неэффективна или вообще невозможна без внедрения декодирования макроопераций.

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

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

Публикации