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

«Как же так? Я тысячу раз забивал на тесты и проектирование, и быстро выкладывал в прод. Я делал похуже, но задача быстрее попадала на прод или в тестирование». На самом деле ты просто быстрее выложил задачу на прод, но не быстрее сделал задачу. Мы заканчиваем задачу тогда, когда к ней уже не нужно обращаться, когда она работает и не требует внимания разработчика. А если после выкладки — через день, два, да даже через неделю или месяц, — приходится срочно править баги, тушить пожары и переписывать код, то мы всего лишь выложили быстрее, но отнюдь не сделали быстрее. И более того, мы потратили гораздо больше усилий. Сравните «сделать спокойно и выкатить на день позже» с «выкатить на день раньше и потом еще 2—3 дня тратить на баги, отвлекая разработчика, срывая текущие планы и переключая контекст».

Когда ты спешишь, суетишься и выкатываешь быстрее, ты на самом деле себя обманываешь. Ты делаешь хуже. Мы тестируем свой код не для того, чтобы себя занять, а чтобы удостовериться в том, что на выходе получится то, что требуется. Мы пишем автотесты не потому, что это прикольно и мы прочитали очередную книжку про TDD, а потому, что они сокращают цикл обратной связи «написал/поправил», и в конечном счёте ускоряют разработку. Мы проектируем API или архитектуру не для того, чтобы чувствовать себя генералами UML, а потому что подумав чуть-чуть в начале, нам не придётся в конце всё переделывать, и дальнейшие правки будут проще.

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

«Это же не эффективно — тратить время на написание супер-универсального или супер-производительного кода.» И нет, качественная работа — это не про супер-универсально, или супер-производительно, или супер-безопасно, или pixel perfect. Качественная работа — это адекватный задаче, продукту и команде уровень универсальности, производительности, безопасности и протестированности кода. Искусство разработки и состоит в том, чтобы найти такое техническое решение, которое можно было бы реализовать в рамках имеющихся ограничений: продуктовых, ресурсных, временных, инженерных, с учётом всей неопределённости.

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

А самое страшное, что снижая планку инженерного качества мы учимся делать хуже. Я много раз видел, как люди, которые привыкли писать код через костыли, побыстрее, даже когда у них много времени, не способны писать код по-другому. Концепция «пока стартуем проект, сделаем по-быстрому, а потом переделаем хорошо» на самом деле не работает. Потому что инженерная культура — это вторая натура, это привычки, и от них крайне тяжело избавиться. Если человек делает хорошо, качественно, то он не может начать делать плохо по щелчку пальцев. Попробуйте сами написать плохой код — вы потратите значительно больше усилий, чем на хороший. У такого человека уже огромный багаж хороших, качественных решений, подходящие для этого инструменты. То же самое касается и тех, кто всегда делает по-быстрому: они также по щелчку не смогут начать писать нормальный код. Хотя им может так и казаться.

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

Я не стану и не советую писать код плохо, нарушать производственный процесс, чтобы сэкономить полчаса, а потом два дня разбираться с багами. Потому что привычка — это вторая натура. И ты либо работаешь хорошо и быстро, либо плохо и медленно. Тесты, рецензирование кода, проектирование, общение с заказчиком, написание кода — это всё инженерный процесс. Если попытаться его сократить, оптимизировать и выкинуть неотъемлемые части, то мы получим плохой процесс, который будет ухудшать продуктивность разработки. Я даже не могу себе представить, от каких инженерных практик я могу отказаться, чтобы писать код хуже, но быстрее. Править код в проде? Отказаться от запуска тестов? Отказаться от написания тестов? Отказаться от продумывания архитектуры и API? Отказаться от CI/CD? Мониторинга и алертинга?

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

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

P.S.: классическая статья Мартина Фаулера на эту же тему

Комментарии (15)


  1. AntonioXXX
    29.07.2021 11:12
    +3

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

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


    1. zuborg
      29.07.2021 11:35
      +1

      Мне кажется, речь в статье немного о другом

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


      1. AntonioXXX
        29.07.2021 11:50
        +2

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

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


  1. laatoo
    29.07.2021 11:53
    +5

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

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


    Чтобы вообще начинать говорить о качестве, нужно определить термин. Качество, оно про что? Про соответствие спецификации? Про соответствие субъективным ожиданиям (!= спецификация/тз) заказчика? Про дешевизну поддержки? Про когнитивную сложность кода? Про перфоманс? Про конверсию?


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


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


  1. jetcar
    29.07.2021 12:31
    +1

    Быстро и качественно не бывает априори. А в аджайле где тебе в самом конце говорят что надо 70% переписать это ещё и означает что всё что до этого успели сделать надо переделать или выкинуть. Другое дело медленный подход когда каждый шаг продумываешь и переспрашиваешь, а нахера оно нужно и почему именно так, тогда в конце выйдет более менее похожее на то что заказчик хотел на самом деле и предусмотрены решения для будущих проблем и возможности расширения. Вот это и есть показатели качества. Если нет тестов то значит всё писалось на коленке не продумывая и последние изменения могут сломать вообще всё.

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


  1. mudriyjo
    29.07.2021 13:01
    +1

    Еще бы экспериментальные данные под это подложить статья была бы сильно полезнее. Тут еще можно играться с точкой пересечения. Как пример сдвинем ее правее и востребованность доработок\продукта может быть равна 0. Можно наложить рассуждения на две модели - для примера рассмотрел два варианта запуск стартапа и разработку коробочного решения с понятным функционалом и планом на 3-5 лет


  1. mvv-rus
    30.07.2021 01:11
    +1

    На самом деле ты просто быстрее выложил задачу на прод, но не быстрее сделал задачу.

    Нет, выложил на прод (для группы, работающей над программой в целом) или влил написанный кусок сделанного кода в общую программу (для конкретного разработчика) — это и означает сделал: эта конкретная задача уже решена
    При этом у программиста есть масса способов сократить усилия (а, следовательно — и время) разработки за счет потери того, что обычно относят к «качеству». И отсутствие обработки достаточно редких ошибок — это только один из них. Есть и другие.
    Например, можно оставить в программе «магиеское число» вместо того, чтобы заменить его именованной константой, назначение которой понятно из ее имени: экономится время на придумывание имени, на запись определения константы в нужное место программы (обычно это нужно делать где-то в другом месте). Можно скопипастить в несколько мест почти повторяющиеся куски программы и немного подправить их по месту, вместо того, чтобы оформить их в виде подпрограммы, годящейся для всех мест использования этого похожего кода. Можно даже написать спагетти-код, в котором управление передается туда-сюда вне всякой последовательности (промисы в JS или продолжения задач в C#, вкупе с вызовами подпрограмм/методов, определенных «где-то ещё», и передаваемых туда ссылок на методы, дают массу возможностей сделать это даже без использования банального goto). И так далее.
    В отличие от отсутствия обработки редких ошибок программа при этом хуже работать не будет — но изменять ее будет труднее. То есть, прямо требуемый с работника-программиста результат будет достигнут — но за счет побочных эффектов.
    И, кстати, такая экономия — она, вообще-то, как раз соответствует материальным интересам наемного работника-программиста: он сделал требуемое с него, пусть за те же деньги, но затратив меньше своих собственных усилий. Потому объективно контроль за надлежащим уровнем качества — это, если подходить объективно и материалистически есть исключительно проблема менеджера.
    А побуждать наемного работника брать на себя решение этой проблемы — что по факту делается в этой статье — это попытка навязать работнику ложную потребность действовать вопреки своим материальным интересам.


  1. HellWalk
    30.07.2021 10:35
    +1

    Ты можешь делать либо быстро и качественно, либо медленно и плохо

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


  1. qw1
    30.07.2021 11:30

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


    1. HellWalk
      02.08.2021 09:00

      Если заказчик не знает, что он хочет (или у него хотелки меняются по пять раз на неделе), то это проблемы заказчика, а не программиста, вы не находите?


      1. qw1
        02.08.2021 10:33

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


        1. HellWalk
          09.08.2021 10:10

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

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

          Другое дело, что для многих россиян терпеть - это в крови.


  1. MShevchenko
    30.07.2021 12:41
    +4

    Я сейчас открою один секрет, только ты не обижайся.

    Качество и скорость никак не связаны. Это раз.

    А во вторых если у вас отсутвует техническая документация на то что вы наваяли или она есть, но просто "для галочки", для неё нет процесса QA, или она его не проходит - качестао вашего "изделия" равно нулю.

    Третье, если вы используете любую вариацию аджайла (еще лучше скрама) в его СНГ-ешной интерпретации, т.е. над ним не построено нормального полноценного водопада - качество вашего кода равно нулю. А еще скорее отрицательно.


    1. alexeyohilkov
      30.08.2021 18:37

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


  1. dushinYu
    06.08.2021 17:34

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

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