Рассмотрим такое проектное ограничение, как «антипрецедент». Наряду с широко известным понятием «прецедент» он применяется при определении проектных требований к информационной системе.
При определении требований к проекту создания информационной системы возникает немало сложностей, обусловленных недостаточно четкой формализацией процедуры сбора и фиксации этих требований. На этапе анализа некоторые малозначительные требования попадают в проектную документацию, поскольку кажутся важными. Напротив, требования, которые кажутся малозначительными или очевидными, вообще не попадают в проектную документацию либо попадают в нее на завершающих стадиях проекта, что приводит к дополнительным издержкам на их реализацию.
Под требованием к информационной системе понимают контрактное обязательство подрядчика, который гарантирует, что по завершении проекта система будет поддерживать определенную функциональность, а также обязуется удовлетворить какие-либо другие проектные и системные ограничения [1]. Обычно все, что не подпадает под требования к системе и не сформулировано в проектных ограничениях, таковым не является, и подрядчик волен реализовать это по своему усмотрению.
Можно предположить, что любой вопрос должен согласовываться с заказчиком и утверждаться им, но на практике число «мелких» решений, принимаемых исполнителем на свой страх и риск, оказывается весьма значительным. Это обусловлено необходимостью снижения накладных расходов на согласование требований и желанием ускорить разработку. Последнее часто оказывается большой проблемой, поскольку далеко не все существенные требования формализуются должным образом и фиксируются в проектной документации как ограничения. Наибольшие сложности вызывают так называемые «очевидные требования», поскольку по мере развития проекта представление об «очевидности» претерпевает значительные изменения.
Классическим подходом является фиксация как можно большего числа требований в проектной документации. При этом подразумеваются значительные расходы на предварительный анализ предметной области, поиск очевидных и неочевидных проблем. Необходимо отметить, что фиксация большого количества требований порождает трудности их поддержки в актуальном состоянии (так, при относительно частом изменении требований резко возрастает вероятность их взаимного противоречия), что влечет за собой дополнительные расходы.
На практике проектные требования часто разделяют на функциональные и нефункциональные. Необходимость этого продиктована принципиально разными способами сбора, описания и формулирования таких требований. Скажем, состав нефункциональных требований к системам определенного класса обычно не изменяется, хотя их количественные показатели (время вывода экрана, число одновременно поддерживаемых пользователей и т.п.) претерпевают изменения. Напротив, функциональные требования к разным системам принципиально различаются.
Для описания различных групп требований используются и разные подходы. Так, для описания нефункциональных требований к производительности системы их часто задают в виде максимального времени открытия экрана (в секундах) при определенном количестве одновременно работающих пользователей. Очевидно, что для фиксации функциональных требований столь четкий механизм описания в общепринятых единицах измерения (секунды, штуки и т.п.) не подходит. Среди множества способов установки таких требований одним из наиболее популярных является прецедентное представление (Use-Case). В литературе его определяют как архитектурное представление, описывающее выполнение в системе критичных прецедентов [1].
Прецеденты — это последовательности действий, выполняемых системой и дающих видимый результат (например, «Разместить заказ», «Перевести средства с одного счета на другой», «Сгенерировать отчет»). Они могут быть выражены как в текстовом виде, так и в виде UML-диаграмм (Use Case Diagram). Прецеденты позволяют определить желаемое поведение системы, а в случае фиксации с их помощью функциональных требований — ее обязательное поведение. Отсутствие реализации какого-либо прецедента или его неправильная реализация расценивается как несоответствие между системой и спецификацией, что, в свою очередь, может быть определено как нарушение условий договора.
Однако не все функциональные требования можно описать в рамках прецедентов. И если учесть, что зачастую функциональные требования определяются только в виде прецедентов, то станет понятно: некоторые функциональные требования вообще не попадают в проектную документацию. Одним из наиболее опасных скрытых видов требований являются так называемые «антитребования», или антипрецеденты.
Примером прецедента и антипрецедента может служить такая пара: «Система должна предоставлять возможность генерации отчетов в формате HTML» и «Система не обязана предоставлять возможность генерации отчетов в формате PDF». Это противопоставление еще более очевидно выражается англоязычными утверждениями System should/must not do smth («системе запрещается делать») и System need not (to)/does not have to do smth («система может делать, но не должна»). Авторам спецификаций и прочих документов рекомендуется обратиться к RFC 2119 [2], где закреплено употребление конкретных модальных глаголов при описании требований.
На практике обсуждение требований часто происходит на протяжении продолжительного времени, поскольку в этом процессе могут участвовать разные — и постоянно меняющиеся — сотрудники. Какие-то положения обсуждаются в устной форме, какие-то — в виде переписки между участниками проекта, но в любом случае вероятность потери подобной информации остается существенной. Это дает возможность для последующих спекуляций с обеих сторон — разработчика и заказчика. Особенно остро встает вопрос в период сдачи системы и ее ввода в эксплуатацию, когда начинают поступать первые жалобы от пользователей.
Известно, что ожидания пользователей часто расходятся с тем, что было выявлено и, главное, зафиксировано на этапе анализа и составления спецификации. Обусловлено это тем, что системный аналитик представляет себе будущую систему как работающую в идеальных бизнес-условиях. Зачастую недостаточно учитываются нефункциональные требования, что приводит к ограничению возможностей применения системы в конкретных условиях.
Рассмотрим такую характеристику, как реакция системы при работе под определенной нагрузкой. Вот пример формулировки: «При работе с системой пользователь не должен ожидать открытия типичной экранной формы более 5 секунд». Эта формулировка содержит сразу несколько потенциально опасных моментов: в ней дается расплывчатое определение «типичная экранная форма» и ничего не говорится о нагрузке на систему, то есть о том, сколько пользователей одновременно работают с ней, каковы их типичные сценарии работы, сколько времени они затрачивают на просмотр экрана и т.п. При внесении подобной формулировки в спецификацию на систему это спровоцирует множество недоразумений.
Самый очевидный способ предотвращения таких проблем — четкое недвусмысленное описание подобных требований, рекомендуемое, например, в RUP. Однако если подобная формулировка большинства нефункциональных требований принципиальна возможна, то по отношению к функциональным требованиям она трудно осуществима ввиду технико-экономических причин. Скажем, далеко не всегда удается задать все возможные сценарии для каждого прецедента. Такая практика резко увеличила бы сроки и стоимость проекта, ощутимо «затянув» стадию анализа и предпроектной подготовки.
Нередко проблема решается с помощью итеративной разработки, при которой часть требований воплощается, и система поступает в опытную эксплуатацию. Однако это не решает проблему полностью, а лишь смягчает ее. Во-первых, на этапе выявления требований по-прежнему остается много нерешенных вопросов и деталей, которые никак не задокументированы, поскольку считаются очевидными. Как следствие, они неверно толкуются конечными разработчиками или вовсе не реализуются. Во-вторых, отсутствие фиксации деталей резко осложняет планирование последующих итераций, поскольку лишает аналитиков и представителей заказчика ценной информации: какие решения были отвергнуты, по какой причине, были ли они запланированы на последующие итерации либо отвергнуты как принципиально невыполнимые или экономически неоправданные?
При решении таких проблем на помощь может прийти антипрецедент. Четко фиксируя на этапе анализа то, что от системы не требуется, можно подстраховаться от последующих необоснованных претензий заказчика, что крайне важно для успешного завершения проекта. В свою очередь, заказчик более четко осознает границы и функциональные возможности будущей системы. Например, когда в требованиях явно указывается, что системе нет необходимости генерировать отчеты в формате PDF, то представители заказчика (и даже конечные пользователи) своевременно узнают об этом. Если они сочтут такую возможность необходимой, можно будет изменить спецификацию, задолго до того, как система будет сдана в эксплуатацию. Как следствие, внесение изменений в спецификацию обойдется гораздо дешевле. Если же заказчик не уделит должного внимания просмотру требований, исполнитель получит веское формальное обоснование ограничений при разработке.
Для предотвращения возможных недоразумений или разногласий рекомендуется фиксировать антипрецеденты на этапе анализа в спецификации или ином аналогичном документе наравне с обычными прецедентами. Очевидно, что подобная практика не может быть распространена на все возможные антипрецеденты (их множество, вообще говоря, бесконечно). Важно достигнуть разумного компромисса, для чего предлагается принять следующее правило. Если прецедент мог быть сформулирован как обычный (не антипрецедент), но по каким-то причинам (например, экономико-временным, маркетинговым либо из-за несоответствия некоторым нефункциональным ограничениям) решено этого не делать, то рекомендуется сформулировать и занести соответствующее утверждение в спецификацию как антипрецедент.
Ввиду практической направленности антипрецедента это понятие не стоит понимать очень узко или буквально. Коллективу разработчиков имеет смысл установить свои правила формулирования антипрецедента, наиболее приемлемые для конкретного проекта. Однако нелишне придерживаться такой рекомендации: чем больше людей принимают участие в составлении и формализации требований, тем более тщательно следует фиксировать проектные решения, и в данном случае антипрецедент может оказать существенную помощь.
В процессе разработки требования часто изменяются, как и состав работающих над ними сотрудников, а в результате создаваемое программное обеспечение оказывается не соответствующим ожиданиям пользователей, хотя формально полностью укладывается в рамки зафиксированных требований. Если же какое-то требование было включено в документацию как антипрецедент (с возможным пояснением причины этого), то впоследствии, скажем, при запуске второй версии системы, членам проектной команды будет проще разобраться в ситуации и внести изменения в проектные решения. Например, окажется, что предпосылки какого-либо антипрецедента устранены, а потому функциональность системы можно расширить.
Литература
- Ф Крачтен. Введение в Rational Unified Process. М.: Вильямс, 2002.
- RFC 2119. Key words for use in RFCs to Indicate Requirement Levels.
Илья Бочков (preacher@argussoft.ru) — эксперт компании Argussoft (Москва).
Практика антипрецедентов
В одном из недавних проектов разработки и адаптации программного комплекса для американского заказчика обсуждалось его требование дополнить систему средствами автоматической проверки на уникальность серийных номеров товаров, генерируемых этой системой или вводимых вручную. Проблема заключалась в том, что, во-первых, реализация данного требования могла привести к снижению производительности системы, а во-вторых, номера уже вводились полуавтоматически из другой учетной системы, с которой предстояла интеграция и в которой была обеспечена такая проверка.
Чтобы сэкономить трудозатраты и избежать снижения производительности системы, в спецификацию было явно внесено антитребование. Оно гласило, что в системе нет необходимости обеспечивать проверку серийных номеров на уникальность и что проверка возлагается на пользователя. На момент обсуждения спецификации это устроило стороны, но когда дело дошло до сдачи проекта и введения его в эксплуатацию, заказчик начал предъявлять претензии. Он утверждал, что система не работает, как положено, а именно — позволяет пользователям вводить неуникальные серийные номера. В ответ разработчик указал ему на антитребование, зафиксированное в спецификации, и заказчик оплатил дополнительные работы, которые были связаны с внесением в систему такой функциональности. Подчеркнем еще раз: все утверждения были явно сформулированы, и заказчик мог обратить на них внимание раньше.