О качестве ПО и почему оно такое. Взгляд на проблемы бизнеса с точки зрения технического специалиста

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

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

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

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

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

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

На таких энтузиастах и держится индустрия

На таких энтузиастах и держится индустрия

Для начала определимся с тем, что такое качество ПО. 

К нему относят следующий набор критериев:

1. Отсутствие багов.

2. Быстродействие.

3. Оптимизация (то, сколько ПО во время работы занимает памяти, оперативной памяти и ресурсов процессора).

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

С первым пунктом все понятно. Баги либо есть, либо их нет.

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

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

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

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

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

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

С этими понятиями определились. 

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

Сценарий 1

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

И у вас есть 3 пути.

1. Найти что-то готовое на рынке.

2. Найти IT-компанию, которая в качестве подрядчика вам эту систему реализует.

3. Набрать собственный штат IT-шников, который вам эту систему реализует.

Предположим, готового решения на рынке не оказалось, и вы решаете найти IT компанию, которая вам всё сделает.

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

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

Это и будет критерием выполнения или невыполнения обязательств со стороны подрядчика. 

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

Что это значит для компании-подрядчика? А значит, что есть сумма, которую компания должна получить от вас за определённый выполненный объём работ. И чтобы заработать на этом денег, затраты на разработку системы как минимум не должны превысить эту сумму, а вообще-то должны быть ниже. 

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

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

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

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

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

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

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

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

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

Сценарий 2

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

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

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

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

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

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

Сценарий 3

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

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

1. Если проблемы совсем очевидны и продолжать без их решения будет ещё дольше и дороже.

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

Итогом всего этого становится MVP, которое объективно сырое, и в случае когда у вас на рынке уже есть конкуренты. Вашим маркетологам и отделу продаж нужно очень сильно постараться, чтобы его продать.

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

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

В случае же если избыток есть, нужно ещё умудриться продать эти работы тому самому «дяде, который за всё платит».

Почему «качать» качество очень тяжело даже если деньги есть?

7f37d1a1ff64494344229f912db430aa.png

1. Понятие поддерживаемости кода, как правило, малопонятная для бизнеса вещь в принципе.

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

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

Потому что система может начать работать на 40% быстрее, может на 20%, на 10% или даже на 5%. В таком случае разница может вообще оказаться незаметной. Точно узнать мы это можем только после того, как работы будут проделаны. А это риски, на которые не каждый готов пойти. 

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

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

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

Почему стоимость разработки растет?

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

1. Любой код всегда превращается в легаси.

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

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

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

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

2. Бюрократизация.

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

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

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

Грубо говоря, тот самый «дядя, который за всё платит», может переплачивать от 10%, а в некоторых случаях и до 50% только за то, чтобы регулярно смотреть на то, за что он собственно платит. Ведь это всё тоже проделываемая работа, которая либо отнимает время действующих сотрудников, либо это делается с привлечением новых.

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

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

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

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

Вот такая вот бизнес-боль, описанная техническим специалистом. Спасибо за внимание!

1fdc48f35f2b4bb9adbf2480f7845572.png

© Habrahabr.ru