Не доверяйте бизнесу в технических вопросах

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

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

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

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

“Это понятно, но что это значит для разработчика? И при чем здесь технические вопросы?” — вот об этом и пойдет речь.

Бремя ответственности

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

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

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

Профессионализм

Не стоит думать, что SAP-консультант, концепционист или бизнес-аналитик не разбираются в своей области. Обычно более чем разбираются. Проблема в том, что ответственные за реализацию фаз, предшествующих написанию кода, неосознанно (а иногда и специально) играют в “сломанный телефон”.

В классическом SAP-проекте представитель бизнеса не является экспертом ни в технических аспектах реализации его задачи, ни в ее проекции на инфраструктуру SAP, иногда и сами продукты SAP видит впервые, а также часто сам не может четко сформулировать для себя полную картину своих требований. То, что он умеет — это вести свой бизнес, зарабатывать компании деньги, делать то, что у него получается лучше всего. А внедрять или настраивать SAP и дорабатывать пользовательские расширения не умеет, поэтому и нанял консалтинговую компанию или открыл IT-подразделение с аналогичным функционалом. Поэтому к его просьбам нельзя относиться как к истине в последней инстанции, как нельзя различить племянников Скруджа МакДака на черно-белом телевизоре.

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

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

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

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

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

Вот еще одна: Разработчик понимает, что вместо отношения 1:1, описанного в задаче, имеет дело с 1:N. Это очень распространенная проблема, связанная с тем, что консультант не изучает в полной мере контекст описываемой задачи. Самый очевидный и до боли частый пример - чтение данных из таблицы. Иногда консультант даже не понимает разницу между таблицей и структурой в SAP. Но даже понимание не спасает от ситуаций, когда в ТЗ указывается одно из нескольких ключевых полей. И на вопрос об остальных возможных значениях или о константах для консистентности выборки, и после объяснений, как и когда это перестанет работать, включается сломанный телефон: “клиент сказал, что там всегда будет одна запись!”. Да, сказал. Потому что он забыл, что через полгода открывается еще один филиал. Или склад. Или язык. Или валюта. Или не знал, и не должен знать. Он вообще может не понимать сущность кардинальности данных. А консультант должен это предусмотреть. Или хотя бы уточнить после получения фидбека от разработчика.

Но однажды в такой ситуации я получил просто потрясающий комментарий:

Заказчик сказал так! Ну и пусть сломается, еще раз нам же заплатят, чтобы мы это исправили!

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

Технический долг

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

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

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

В итоге мы получили задачу, в которой явно видна проблема, которая требует устранения прямо сейчас, иначе она всплывет в будущем с непредсказуемыми последствиями. Но нас убеждают в том, что нужно просто сделать как есть и “перебросить мячик” дальше. Эту проблему нужно как-то решать, и возможные пути решения я могу условно разделить на два вида:

  • Построение обратной связи;
  • Решение без обратной связи.

Построение обратной связи

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

Описывайте не причины, а последствия

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

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

Говорите на языке бизнеса. Оперируйте цифрами, а не терминами

Для разработчика технические детали значат очень многое. Для представителя бизнеса - ничего. Завтра он вообще может перейти с SAP на другие решения. Самые убедительные аргументы не будут поняты, как если бы француз пытался аргументировать свою точку зрения вьетнамцу. Говорите в разрезе ценностей бизнеса: что он потеряет, если не исправить проблему сейчас? Во сколько дней простоя выйдет исправление пятиминутной проблемы через полгода? Что произойдет, если в маршрутный лист, в котором зафиксирована таблица на десять строк, выгрузят двенадцать записей? Или в бухгалтерской форме отчетности не подгрузится актуальный курс валюты? На такой вопрос бизнесу легко будет дать быстрый и продуманный ответ. А если вы не можете задать вопрос в таком ключе, стоит еще раз подумать, а действительно ли эта проблема так важна?

Не предлагайте варианты, которые не считаете приемлемыми

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

Например, у вас есть варианты:

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

Однако часто для клиента это может звучать иначе:

  1. сделать дорого и долго;
  2. сделать быстрее и дешевле;
  3. идеальное решение всех проблем!

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

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

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

Решения без обратной связи

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

Всегда делайте программу отказоустойчивой, даже в случаях, не описанных в ТЗ

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

Однако в программе никогда не должно быть “темных мест”. Вся обработка должна выполняться явно, не должно быть никаких неожиданностей. Для этого программу нужно делать отказоустойчивой. Как этого добиться?

Продумывайте любые возможные варианты “развития событий” в программе и делайте подходящую обработку.

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

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

Доверяйте только фактам

Зачастую ситуация, которую представляет пользователь или консультант, может отличаться от того, как реально функционирует программа. Причин может быть много - технические особенности реализации какой-то задачи, неправильная интерпретация, отсутствие необходимого опыта у автора кода, исторические решения, изменения, произошедшие в бизнес-логике, которые забыли внести в код (встречал даже такое, что после обновлений в спецификации консультант говорил мне: “Я нашел у тебя ошибку! Работает не так, как в спецификации!”. Конечно, ведь программа сама почему-то не уследила за изменениями бизнес-процесса и не обновилась, а программисту зачем сообщать об изменениях? Не работает — значит он и виноват, сам же писал).

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

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

Ориентируйтесь на удовлетворенность клиента

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

Это простое правило поможет найти выход из сложных ситуаций. Каким бы сложным не был путь информации из головы заказчика для клавиатуры программиста, насколько сломанным бы не был связующий их телефон, насколько паршивой бы не была обратная связь - всегда ориентируйтесь на то “А будет ли это тем, что хотел пользователь, даже если и не учел такой вариант? Будет ли ему приятно работать с программой, или он будет бороться с ней?”

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