Существует большая книга под названием « Требования к программному обеспечению», написанная Карлом Вигерсом о требованиях к программному обеспечению. По моему мнению, это нужно прочитать каждому программисту. Мне не нужно повторять то, что он говорит, но есть несколько очень простых и очень типичных ошибок, которые мы продолжаем делать в наших спецификациях. Я вижу их в наших документах снова и снова, поэтому я решил обобщить их. Итак, вот они, десять самых критических и типичных из них, с точки зрения программиста, читающего документ спецификации.
В главе 4.3 известного стандарта IEEE 830-1998 говорится, что хорошая спецификация должна быть правильной , однозначной , полной , последовательной , ранжированной , проверяемой , модифицируемой и отслеживаемой . Всего восемь качеств. Затем стандарт объясняет их один за другим на довольно простом английском языке. Но у нас есть время, чтобы прочитать эти скучные стандарты? Они предназначены для преподавателей университетов и сертификационных советов. Ради Бога, мы практикующие! … Подожди, я шучу.
Независимо от того, насколько мал проект и насколько мы практичны, всегда есть документ, который объясняет, что нужно сделать, и его можно назвать «спецификацией требований к программному обеспечению», или «спецификацией», или просто «спецификацией». Конечно, есть много места для творчества, но мы инженеры , а не художники. Мы должны следовать правилам и стандартам, в основном потому, что они облегчают наше общение.
Теперь я подхожу к своей точке. Спецификации, которые я обычно вижу, нарушают почти все восемь принципов, упомянутых ранее. Ниже приводится краткое изложение того, как именно они это делают. Кстати, все примеры взяты из реальных документов в реальных коммерческих программных проектах.
Нет Глоссарий или Грязный
Как насчет этого:
UUID is set incrementally to make sure there
are no two users with the same account number.
В чем разница между UUID и номером счета? Это то же самое? Вроде так, верно? Или, может быть, они разные … было бы здорово узнать, что означает UUID. Это «уникальный идентификатор пользователя» или, возможно, «унифицированный дескриптор идентификации пользователя»? Я понятия не имею. Я заблудился и хочу найти автора этого текста и сделать что-то плохое с ним … или с ней.
Мы пишем для того, чтобы вас поняли, чтобы не впечатлить читателя
Я уже писал, что у худших технических спецификаций нет глоссариев . По моему опыту, это самая большая проблема во всех необходимых документах. Это не проза! Это не любовное письмо! Это техническая документация. Мы не можем манипулировать словами ради веселья. Мы не должны использовать спецификации продукта только для самовыражения. Мы пишем для того, чтобы вас поняли, а не чтобы произвести впечатление на читателя. И здесь правило такое же, как и с диаграммами : если я вас не понимаю, это ваша вина.
Вот как этот текст будет выглядеть после правильного переписывания:
UUID is user unique ID, a positive 4-bytes integer.
UUID is set incrementally to make sure there
are no two users with the same UUID.
Теперь лучше?
Таким образом, первая и самая большая проблема — это легкомысленное использование терминов и просто слов без их предварительного определения в глоссарии.
Вопросы, обсуждения, предложения, мнения
Я видел это совсем недавно в спецификации продукта:
I believe that multiple versions of the API
must be supported. What options do we have? I'd
suggest we go with versioned URLs. Feel free to
post your thoughts here.
Да, этот текст дословно присутствует в документе с требованиями. Во-первых, автор высказывает свое личное мнение по этому вопросу. Затем автор спрашивает меня, какие возможные варианты есть. Затем он предлагает мне кое-что рассмотреть, а после этого он приглашает меня на беседу.
Найдите все свои ответы перед написанием документа, за это вам и платят
Впечатляет, правда? Очевидно, что автор обладает очень творческой личностью. Но мы должны держать этого человека как можно дальше от проектной документации. Это не то, что оценивает документ с требованиями. Что ж, мы ценим креативность, но эти четыре вещи строго запрещены: вопросы, дискуссии, предложения и мнения.
Спецификации не могут иметь никаких вопросов . Кому адресованы эти вопросы? Я, программист? Я должен внедрить программное обеспечение или ответить на ваши вопросы? Я не заинтересован в мозговом штурме с тобой. Я ожидаю, что вы, автор требований, расскажете мне, что нужно сделать. Найдите все свои ответы перед написанием документа. Это то, за что тебе платят. Если у вас нет ответов, поместите туда что-то вроде TBD («будет определено»). Но не задавай вопросов. Это раздражает.
Документ с требованиями не является дискуссионным форумом. Как читатель спецификации, я ожидаю увидеть, что именно нужно сделать без всяких «возможно» или «мы могли бы сделать это по-другому». Конечно, вам нужно обсудить эти вопросы, но сделайте это, прежде чем задокументировать. Сделайте это где-нибудь еще, как в Skype, в Slack или по электронной почте. Если вы действительно хотите обсудить в документе, используйте Google Docs или Word с отслеживанием версий. Но когда обсуждение закончится, удалите его историю из документа. Его присутствие только смущает меня, программиста.
Нет необходимости форматировать требования как предложения . Просто скажите, что нужно сделать и как должно работать программное обеспечение, не опасаясь ошибиться. Обычно люди прибегают к внушению, когда боятся сказать это прямо. Вместо того, чтобы говорить «приложение должно работать на Android 3.x и выше», они говорят: «Я бы предложил сделать приложение совместимым с Android 3.x и выше». Увидеть разницу? В первом предложении автор пытается избежать личной ответственности. Он не говорит «точно Android 3.x;» он просто предлагает. Не будь трусом; скажи прямо. Если вы допустите ошибку, мы исправим вас.
И, конечно, мнения не ценятся вообще. Это не письмо другу; это официальный документ, который принадлежит проекту. Через несколько месяцев или недель вы можете покинуть проект, и кто-то другой будет работать с вашим документом. Спецификация — это контракт между спонсором проекта и командой проекта. Мнение автора документа здесь не имеет никакого значения. Вместо того, чтобы отмечать «кажется, что Java будет быстрее» и предлагать «мы должны его использовать», скажем «Java быстрее, поэтому мы должны его использовать». Очевидно, вы положили его туда, потому что вы так думали. Но как только он появится, нам все равно, кто это сделал и что вы подумали об этой проблеме. Информация только запутает нас больше, так что пропустите ее. Просто факты, нет мнений.
Не поймите меня неправильно, я не против творчества. Программисты не роботы, которые спокойно реализуют то, что написано в документе. Но грязный документ не имеет ничего общего с творчеством. Если вы хотите, чтобы я творил, определите пределы этого творчества и позвольте мне поэкспериментировать с ними; например:
Multiple versions of the API must be supported. How exactly
that is done doesn't really matter.
Вот как ты приглашаешь меня быть креативным. Я понимаю, что у пользователя продукта нет никаких оправданий или ожиданий относительно механизмов контроля версий в API. Я свободен делать все, что могу. Отлично, я сделаю это по-своему.
Но еще раз позвольте мне повторить: спецификация — это не доска обсуждений.
Сочетание функциональных и качественных требований
Вот как это выглядит:
User must be able to scroll down through
the list of images in the profile smoothly and fast.
Это типичная ошибка почти во всех спецификациях, которые я видел. Здесь мы смешиваем функциональное требование («для прокрутки изображений») и нефункциональное («прокрутка плавная и быстрая»). Почему это плохо? Ну, нет конкретной причины, но это демонстрирует отсутствие дисциплины.
Такое требование трудно проверить или протестировать, трудно отследить и сложно выполнить. Как программист, я не знаю, что важнее: прокручивать или обеспечивать быструю прокрутку.
Также сложно изменить такое утверждение. Если завтра мы добавим еще одно функциональное требование — например, прокрутку списка друзей — мы захотим, чтобы эта прокрутка также была плавной и быстрой. Затем, через несколько дней, мы хотим сказать, что «быстрый» означает менее 10 миллисекунд времени реакции. Затем нам придется дублировать эту информацию в двух местах. Видите, насколько грязным может стать наш документ?
Поэтому я настоятельно рекомендую вам всегда документировать функциональные и нефункциональные требования отдельно.
Требования к микшированию и дополнительные документы
Это похоже на предыдущую проблему и может выглядеть так:
User can download a PDF report that includes a full
list of transactions. Each transaction has ID,
date, description, account, and full amount. The report
also contains a summary and a link to the user account.
Очевидно, что в этом параграфе описаны две вещи. Во-первых, пользователь может загрузить отчет в формате PDF. Во-вторых, как должен выглядеть этот отчет. Первое — это функциональное требование, а второе должно быть описано в дополнительном документе (или приложении).
В общем, функциональные требования должны быть очень короткими: «пользователь загружает», «пользователь сохраняет», «клиент запрашивает и получает» и т. Д. Если ваш текст становится больше, значит что-то не так. Попробуйте перенести часть этого в дополнительный документ.
Неизмеримые требования к качеству
Вот о чем я говорю:
Credit card numbers must be encrypted.
The app should launch in less than 2 seconds.
Each web page must open in less than 500 milliseconds.
User interface must be responsive.
Я могу найти еще много примеров, просто открыв спецификации требований во многих проектах, которые я видел за последние несколько лет. Они все выглядят одинаково. И проблема всегда одна и та же: очень трудно определить действительно проверяемое и измеримое нефункциональное требование.
Да, это сложно. Главным образом потому, что есть много факторов. Возьмите эту строку, например: «Приложение должно запуститься через 2 секунды». На каком оборудовании? С каким количеством данных в профиле пользователя? Что означает «запуск»; это включает в себя время загрузки профиля? Что делать, если есть проблемы с запуском? Они считают? Таких вопросов много.
Если мы ответим на все из них, текст требования заполнит всю страницу. Никто не хочет этого, но иметь неизмеримые требования — еще большее зло.
Опять же, это не просто, но это необходимо. Постарайтесь убедиться, что все требования к качеству выполнены и не имеют двусмысленности.
Инструкция по внедрению
Этот пример иллюстрирует очень распространенную ловушку:
User authenticates via Facebook login button
and we store username, avatar, and email in the
database.
Это микроуправление , и аналитик никогда не должен делать это с программистом. Вы не должны говорить мне, как реализовать желаемую функциональность. Вы хотите дать пользователю возможность войти через Facebook? Так и сказал. Вас действительно волнует, произойдет ли это с помощью нажатия кнопки или как-то еще? Вы действительно заботитесь о том, что я храню в базе данных? Что если я использую файлы вместо базы данных? Это важно для тебя?
Я так не думаю. Только в очень редких случаях это будет иметь значение. В большинстве случаев это просто микроуправление.
Спецификация должна требовать только того, что действительно важно для бизнеса. Все остальное зависит от нас, программистов. Мы решаем, какую базу данных использовать, где будет размещена кнопка и какая информация будет храниться в базе данных.
Вы не должны говорить мне, как реализовать желаемую функциональность
Если вы действительно заботитесь об этом, потому что существуют определенные ограничения более высокого уровня — так и скажите. Но опять же, не как инструкции по реализации для нас, программистов, а скорее как нефункциональные требования, подобные этому:
Login page must look like this (screenshot attached).
We must store user email locally for future needs.
Дело в том, что я ничего не имею против требований, но я категорически против инструкций по реализации.
Отсутствие актерской перспективы
Текст может выглядеть так:
PDF report is generated when required. It is
possible to download a report or save it
in the account.
Проблема здесь в том, что здесь не задействован «актер». Эта функциональность более или менее понятна, но не ясно, кто все это делает. Где пользователь? Это просто история о том, что где-то происходит. Это не совсем то, что нужно программистам для его реализации.
Хороший пользовательский рассказ всегда есть, угадайте, что … пользователь
Лучший способ объяснить функциональность — это истории пользователей. И хорошая пользовательская история всегда есть, угадайте, что … пользователь. Он всегда начинается с «пользователь …», за которым следует глагол. Пользователь загружает, пользователь сохраняет, пользователь щелкает, печатает, удаляет, форматирует и т. Д.
Пользователю необязательно быть человеком. Это может быть система, клиент RESTful API, база данных, что угодно. Но всегда кто-то. «Можно скачать …» — это не история пользователя. Это возможно для кого?
Шум
Как насчет этого:
Our primary concern is performance and an attractive
user interface.
Это шум. Как читатель этого документа, я не являюсь ни инвестором, ни пользователем. Я программист. Мне все равно, какова ваша «главная забота» в этом проекте. Моя задача — реализовать продукт так, чтобы он соответствовал спецификациям. Если производительность является вашей главной задачей, создайте для меня измеримые и проверяемые требования. Я позабочусь о том, чтобы продукт их удовлетворял. Если вы не можете создать требование, не спамите меня с этой неактуальной информацией.
Хорошие программисты должны понять, что значит хорошая производительность, верно?
Я не хочу делиться вашими проблемами, вашими убеждениями или вашими намерениями. Дело ваше. И вам платят за то, чтобы правильно и однозначно перевести все это в поддающиеся проверке и измеримым требованиям. Если вы не можете этого сделать, это ваша проблема и ваша вина . Не пытайся сделать это моим.
Очень часто … подожди. Очень, очень часто Почти всегда. Опять не так. Всегда! Это верно, технические документы всегда полны шума. Некоторые из них имеют немного меньше; у некоторых есть больше. Я считаю, что это признак ленивых и непрофессиональных авторов документов. В большинстве случаев просто ленивый.
Они не хотят думать и переводить свои проблемы, идеи, мысли, намерения и цели в функциональные и нефункциональные требования. Они просто помещают их в документ и надеются, что программисты найдут правильное решение. Хорошие программисты должны понять, что значит хорошая производительность, верно? Давайте просто скажем им, что производительность нас беспокоит, и они что-нибудь придумают.
Нет! Не делай этого. Делай свою работу правильно и позволь программистам делать свою.
И мы, программисты, никогда не должны принимать такие документы. Мы должны просто отклонить их и попросить авторов требований переделать и убрать шум. Я бы порекомендовал даже не начинать работать над продуктом, если в его характеристиках много шума.
Будет работать, нужно работать, нужно работать
Это еще одна очень типичная ошибка:
The API will support JSON and XML. Both formats
must fully support all data items. XML needs to
be validated by XSD schema.
Видите, как грязно это звучит? Есть три разные точки зрения, и ни одна из них не подходит для документа спецификации. Спецификация должна описывать продукт так, как будто он уже существует. Спецификация должна звучать как руководство, учебник или ссылка. Этот текст должен быть переписан так:
The API supports JSON and XML. Both formats
fully support all data items. XML is validated
by XSD schema.
Увидеть разницу? Все слова «необходимо», «нужно» и «будет» просто добавляют сомнение к документу. Для читателя этой спецификации » API будет поддерживать » звучит как «когда- нибудь в будущем, может быть, в следующей версии он будет поддерживать «. Это не то, что имел в виду автор, верно? Там не должно быть никаких сомнений, никакого двойного значения, нет, может быть. API поддерживает. Вот и все.
Возможно, я забыл кое-что важное, но эти проблемы настолько очевидны и так раздражают … Я собираюсь использовать этот пост в качестве простого руководства для наших системных аналитиков. Не стесняйтесь поделиться своим опытом с требованиями документов ниже в комментариях.