Хорошие программисты и сложность
27 октября 2014
Частенько мне встречаются хорошие, на первый взгляд, программисты: они говорят правильные вещи, цитируют отцов основателей, критикуют плохие подходы. К сожалению, на практике они нередко оказываются не настолько хороши.
Чаще всего мешают им фанатичность, нетерпимость к альтернативам и полное отсутствие прагматичного подхода. От них часто можно услышать что-то вроде:
- Код надо обязательно покрыть юнит-тестами на 100%. В тестах надо делать моки через мок-фреймворк.
- Ни в коем случае нельзя писать связанный код.
- Всегда без исключений надо следовать SOLID, DRY, GRASP и т.д.
- Абсолютно все приложения надо строить по DDD.
- Для доступа к данным обязательно нужен крутой ORM.
- Писать документацию нет смысла, потому как она всегда отстаёт от кода. Код — лучшая документация.
- Если в коде есть комментарии, код недостаточно отрефакторен. Всегда можно разделить код и назвать методы так, чтобы отразить предметную область.
- Невозможно построить хорошую архитектуру без ООП.
- И так далее.
Знакомо? Всё это выливается в непрактичные решения, реальной целью которых является доказать собственную правоту и крутость сделав «как учат в умных книгах». Реальность при этом частенько не учитывается.
Не следует забывать, для чего на самом деле мы пишем код. А именно:
- Чтобы он работал и решал поставленные задачи.
- Чтобы его могли прочитать, осознать и изменить другие программисты.
Для пункта номер два следует вносить в код как можно меньше сложности. Оправдана она только в том случае, когда другого выхода нет.
Это не означает, что не надо изучать шаблоны проектирования, читать Фаулера и т.д. Надо. Просто во всём надо знать меру и не бросаться применять прочитанное с особым энтузиазмом и уж, тем более, не стоит это делать, если вы не понимаете, для чего это и как оно упростит вам жизнь (и упростит ли вообще).
Комментарии RSS по email OK
Собственно остаётся только подписаться :) У самого зреет доклад на эту же тематику, более развёрнуто и жестко :)
Правильно говорить и правильно делать это не одно и то же. Очень многие знают как надо, а делают как удобно, как привыкли. Есть даже люди, которые специально делают код запутанным, чтобы впоследствии стать единственным незаменимым человеком, который может работать с этим кодом.
К сожалению, профессионализм и порядочность не всегда идут рука об руку.
Etki, что такое «бугуртация»? Похоже, зря причисляете себя к описанным товарищам, раз допускаете исключения.
Упрощать сложно. Усложнять просто.
Верно описано, для мелких проектов и проектов outsource в основном можно пропускать тесты, DDD и прочие вещи, т. к. это только замедлит процесс разработки, и качество не так важно тут. Если это сложный действительно и долгосрочный проект, в основном такие пишут компании для своих нужд и продают их, а не работают на outsource, то вышеописанные подходы придется применять, т. к. в долгосрочном периоде они дадут прирост как по времени так и по качеству кода. В целом везде свои tradeoffs ;)
Ольга, про тех, кто намеренно путает код я уже писал как-то.
Ragazzo, стоит обратить внимание как я перечислил упомянутое выше ;) Думаю, что прям 100% покрытие тестами не важно в 90% даже сложных проектов.
Sam, конечно нет, тестов буквально на домен и контракты хватит, а остальное это на стейдже ловить или QA, домен обычно небольшой по сравнению с тем что его обслуживает ) главное не тесты и красивый код, а Continuous Product Delivery, ведь деньги платят за продукт, а не за красивый код, что подтверждено многими примерами, в том числе и Microsoft )
Добавлю:
Такие программисты пишут свой код минимум для атомных электростанций, меняться он будет в след раз лет через 10 и без десятка сервис локаторов и депенденси иньекций там не сделать "SELECT COUNT(*) FROM articles;"
В тайне такой программист мечтает сделать свой фреймворк, который будет божественным по определению, но пока пишет на первом зенде или кейке, потому что мир не идеален и как мы все знаем: "пхп в принципе говно, вот на руби..."
Очень протеворичивое мнение) с одной стороны сам писал о подобном, что программисты увлекшись кодописанием забывают о том что проект должен приносить бабло. с другой стороны никто не хочет что бы после написания проекта его выкинули и взяли программиста подешевле на поддержку. А в корпоративном секторе все еще проще все работают на "отцепись" потому что например пол проекта и так делают индусы.
Я вот кслоняюсь к мысли, что это всё зависит от типа мышления человека. Если, допустим, это рационал, ему важнее выстроить правильную систему, а значит, любые методологии помогающие в строительстве систем - SOLID, DDD, TDD, и т.д. будут ему помогать. Конечно, реальный проект может не совсем совпадать с системой, и тут действительно проявятся косяки "системного" подхода.
Мы с тобой иррационалы, нам проще сначала увидеть продукт и наощупь перепробовать разные варианты его построения, чтобы найти максимально эффективен, двигаясь не по системе, а исходя из своего понимания как это должно работать.
А потому, мне кажется, что ты ничего не изменишь этим постом. Кто потребует систему будет её строить, кому она не нужна будут избегать лишних сложностей в виде DDD, TDD, и пр.
P.S. Уточнение: когда я говорю "рациональность"-"иррациональность", я допускаю, что это может быть совсем другой признак, но скорее всего это тоже дихотомия основана на базисе Юнга. Т.е. нельзя быть немного рацио, и немного иррацио, информация воспринимается только так или так.
Что поделать. Сейчас новое поколение растет на хабре, где увы, приводить к печальными последствиям. Люди начитавшись статей пытаются зубрить паттерны. Читают Википедию и видят фигу.
В одной фирме где я читали люди стали про паттерны, про чистый код, но не могли ответить для чего нужен ООП. Львиная доля выходцев с хабар рассуждают и пишут статьи про SOLID, при этом абсолютно не понимают каждый из принципов. Укол от таких людей хуже чем от студентов, которым не успели испортить мозг горе учителя с Хабра
Davert, так я не избегаю и не призываю избегать. Все методологии, паттерны и т.д. не с потолка взяты и действительно помогают. Просто они не решают всех проблем во всех ситуациях. А в некоторых проблем ещё и добавляют.
На 100% согласен с тобой Саш! Это называется программирование ради программирования. Хороший программист, имхо, должен соблюдать грань между правильным (книжным) кодом и скоростью разработки.
Зачастую за этими слепым следованием за различными методиками и принципами теряется изначальная их цель - качественный продукт, а не идеальный сферический код в вакууме.
как будто нам 18 лет 4:)
Alexey Spiridonov, кому?
Не знаю насколько правильны мои мысли, но для себя отметил некоторые стадии роста программиста:
Заметьте, я не разделял на ждунов/мидлов/синьеров. Чаще всего эти характеристики пересекаются только вначале становления человека программистом)
просто вспомнил юнные годы и подобную рефлексию
Начал замечать за собой, что настолько свыкся с неидеальностью мира и невозможностью писать идеальный код, что иногда перестаю писать даже нормальный, например, за именованием переменных слабо слежу, особенно в циклах. Приходится проводить рефакторинг периодический, так как сразу писать нормально отучиваюсь, вгоняя YAGNI в крайность.
AmdY, не, ну так точно не надо. Любые крайности — это нехорошо.
Сам таким был. Автора поддерживаю
@Sam
Вообще я из тех, кто считает, что если на код нет тестов, то он по умолчанию не работает (чем успешно и занимаются 95% плагинов для вордпресса), либо выглядит, как засохший мамонт, потому что его писал школьник, не удосужившийся прочитать про PHPUnit.
Касательно всей ситуации: код без тестов / продуманной архитектуры и наспех написанный код либо используется в каком-то захудалом проекте, из которого, по возможности, надо бежать (в жизни разное бывает, но если есть возможность не писать подобные вещи - нужно ею пользоваться), либо его пишут люди, которым как раз-таки наплевать и на то, как он исполняется, и на тех, кто придет поддерживать этот код. Вся эта байда с CI, стат. анализом кода, всем Quality Assurance придумана не потому, что прикольно пырчить в зеленую полоску с надписью '1000 assertions', а потому что это хоть какие-то гарантии того, что все работает и что был проведен хоть какой-то ревью написанного кода, пусть даже и самим разработчиком.
Еще как.
Потому что первые два пункта выполняются автоматом, если разработчик привык это делать, и это практически не отнимает времени. На грабли с третьим, наверное, все наступали. Да доктрина к опенкарту прикрутится быстрее, чем один разраб напишет все необходимые кастомные sql-запросы.
У меня прямо сейчас проект на вордпрессе (чтоб он подох). Я написал три дропдауна руками, теперь мне нужно добавить пару фич во все три. Угадайте, сколько бы передо мной стояло задач, если бы я не руководствовался мыслями, аналогичными выводам из этого поста? Как меня будет материть следующий разработчик, столкнувшийся с аналогичной задачей? Прочитать и понять-то код он сможет, в этом я не сомневаюсь.
Вся, вся эта штука приводит просто к тому, что ты уверен, что а) код работает и б) возвращаться к нему не надо будет. Когда все пхпшники мира это поймут, наконец-то станет проще дорабатывать сайты на пресловутом вордпрессе, чем переписывать с нуля.
Да, это все отнимает немного больше времени, чем если писать плейнтекстом, но, черт побери, неужели это не компенсируется удовольствием за красиво написанный код? Где профессиональные амбиции, где желание сделать всё красиво? Нужно идти не от "100% покрытие нужно только идеалистам", а "как я могу максимально покрыть код тестами в разумные сроки?".
Полностью солидарен с автором статьи. Только мне кажется, что он сам ещё не до конца избавился от своей фанатичности :)
программисты пишут код для получения денег, и 99% заказчиков глубоко по ... как и на чём он написан :) Хороший пример битрикс - самая популярная коммерческая цмс с ужаснейшим кодом. Остановите тимлида битрикса на парковке перед тем как он залезет в свой новенький крузер и расскажите про шаблоны проектирования, а потом идите на трамвай и домой )))
@Etki У меня друг sеошник, спокойно лепит сайт за сайтом на вордпресе, при этом не знает ни то что о phpunit, но даже о php, а у вас проблемы. Получается, на практике, что он круче разработчика с отличной теорией, раз осилел вордпрес лучше? И это не сарказм.
@Алек
Если у вас проблемы с крузерами, то лично я не вижу наличие крузера препятствием для неправильного написания кода, или, наоборот, признанием того, что человек хороший программист.
@Amdy
С какой стороны он лучший программист, если клепает сайты на вордпрессе? Я не вижу логической связи.
@Etki потому что он не испытывает проблем с wordpress и спокойно разрабатывает продукты на нём. Цель разработки не писать тесты и рассчитывать метрики, а давать результат.
@Алек Недавно меня пригласили в компанию для консультации. У них проблема со срывом сроков. Первая проблема которая обнаружилась, это лавинообразное увеличение задач на поддержку предыдущего мусора. Вторая проблема, то что разработанное ранее, не масштабируется и переписывается полностью.
В итоге терялись деньги(большие деньги) время программистов. Некоторые компании готовы терять деньги на новых и новых программистов на Битриксе, что бы те ездили на "крузерах". А некоторые, хотят быстро развиваться не раздувая штат.
@Amdy а перечитайте мой предыдущий (который длинный) комментарий, что ли.
Пост выглядит забавно по своей структуре: «Догмы это плохо! .... Вот вам ещё парочка догм!». Куда целился этот пост? В какую аудиторию? На какой результат?
Разумно, в то же время, например почитать «Совершенный код», Макконнелла, человек не зря 800 страниц написал. Там примерно про то же, но с разбором ситуаций и кучей хороших примеров. Несмотря на название, там много всего, в том числе, по прагматичному подходу, а далеко не только по коду.
Etki,
Почему нельзя, например, покрыть 70% действительно важного юнитами, а остальное добить приёмочными и функциональными? Времени можно сэкономить прилично, уверенность, что ничего не сломалось в целом, так и так будет.
Вы забываете про фазу прототипирования. Уже успешный проект, как правило, при внедрении фичи делает 2—3 реализации и проводит вариационное тестирование на фокус группах. Остаётся в итоге одна, которую можно покрыть, например, функциональными тестами. Остальной код безжалостно удаляется. Ну и большинство стартапов — они, по сути, большие прототипы. У них задача такая — прояснить в голове создателя как надо сделать нормально и затем быть убитыми. Для таких прототипов важен бюджет и скорость, а качество должно быть даже не хорошим, а просто достаточным.
Зависит от разработчика и ситуации. Например, многие понимают DRY как отсутствие копипаста и фанатично делают extract method даже там, где сегодня это копипаст, а завтра придётся обратно сливать методы чтобы нормально разделить логику.
Перед вами стояло бы две задачи:
И именно в таком порядке надо делать потому как это могло и не понабиться в последующие три года.
Нужно идти от того, что нужно заказчику, а не удовлетворять по тихому свои амбиции за его счёт.
Roman, пост целился во всех и единственный посыл в том, что крайности — это, в большинстве случаев, плохо.
| например, покрыть 70% действительно важного юнитами
Сомневаюсь что большинство разработок имеет хоть какие то тесты и ничего, на плаву. И даже деньги зарабатывают :)
А ещё знаю, что быстро развивающиеся продукты, которые зарабатывают деньги не имеют чёткой и устоявшейся функциональности и покрытие тестами или развитием через TDD просто сдохнут от переписывания тестов :)))))
Вообще - можно, я про 100% нигде и не написал. Но не нужно, потому что это разные слои. Потому что фича может внедрена в ядро сегодня, а гуи к ней напишут через два года. Потому что задача теста - точно указать, где и что отвалилось, и сделать это в тот же момент, как отвалилось. Потому что опять можно забыть про реюзабилити underlying кода, на интеграционных тестах всё ок, потому что часть функционала урезается или поступает ограниченный формат данных, а вставляешь в другой проект, и все падает. И снова отлаживаешь, вместо того, чтобы сделать это сразу.
Экшены из контроллеров - да, но их и на этапе разработки в ручном режиме можно оттестить. Выкидывать работающие методы из модели, которые еще миллиард раз могут понадобиться - ну хз. На словах все круто, сейчас напишем, будет пинать, пока не заработает (обычно на дебаг уходит столько же времени, сколько на написание тестов), подопрем костылями и будем ждать момента, когда это все можно-нужно будет переписывать, главное чтоб работало. К моменту внедрения следующей фичи половина уже отвалилась, а восстановление неизбежно тянет в другие связанные модули, и все буксует уже на старте. Через два года там уже непонятно, с какой стороны подступаться.
Вот тут неплохо Андрей Аксёнов раскрывает сорта программистов, ну и вообще иногда правильные вещи youtu.be/LodXWv234Kg
Sam, ну с таким посылом конечно соглашусь, просто ведь слишком абстрактно подано, почему и появляется столько трактовок в комментах. Можно подумать, что пост в общем о том, что крайности это плохо (и это, как выяснилось верно). А можно из этого же текста подумать что плохо это именно то что перечислено в первом списке, а хорошо: «Можно проще — делайте проще.». Проблема в том, что этот тезис в таком виде крайне опасен, особенно для начинающих программистов. Без дополнительных разъяснений, он может привести к тому, что примитивизм будет перепутан с простотой, а это совсем не одно и то же.
Roman, есть такое. Прибил на всякий пожарный «Можно проще — делайте проще.».
В любом случае, если стремится к идеалу, можно выработать у себя привычки писать "идеально". Я знаю людей которые программируют по 6+ лет, и до сих пор пишут "а лишь бы работало". И оно работает. Правда потом когда садишься править \ дорабатывать этот код - понимаешь все прелести "идеального" подхода. И наоборот, встречаю и таких, которые пишут код не больше года, но в них "старшие" со старту воспитывали этот идеализм. Вот как раз их код мне приятней фиксить \ дорабатывать.