Основы Программной Инженерии (по SWEBOK)

Сергей Орлик

Введение

В конце 90-х годов прошлого века знания и опыт, которые были накоплены в индустрии программного обеспечения за предшествующие 30-35 лет, а также более чем 15-летних попыток применения различных моделей разработки, все это, наконец, оформилось в то, что принято называть дисциплиной программной инженерии – Software Engineering. В какой-то мере, такое формирование дисциплины на основе широко распространенного практического опыта напоминает те процессы, которые происходили в управлении проектами. Возникали и развивались профессиональные ассоциации, специализированные институты, комитеты по стандартизации и другие образования, которые, в конце концов, пришли к общему мнению о необходимости сведения профессиональных знаний по соответствующим областям и стандартизации соответствующих программ обучения.

Программная инженерия как дисциплина

В 1958 всемирно известный статистик Джон Тьюкей (John Tukey) впервые ввел термин software – программное обеспечение. В 1972 году IEEE* выпустил первый номер Transactions on Software Engineering – Труды по Программной Инженерии. Первый целостный взгляд на эту область профессиональной деятельности появился 1979 году, когда Компьютерное Общество IEEE подготовило стандарт IEEE Std 730 по качеству программного обеспечения. После 7 лет напряженной работы, в 1986 году IEEE выпустило IEEE Std 1002 “Taxonomy of Software Engineering Standards”.

Наконец, в 1990 году началось планирование всеобъемлющих международных стандартов, в основу которых легли концепции и взгляды стандарта IEEE Std 1074 и результатов работы образованной в 1987 году совместной комиссии ISO/IEC JTC 12. В 1995 году группа этой комиссии SC7 “Software Engineering” выпустила первую версию международного стандарта ISO/IEC 12207 “Software Lifecycle Processes”. Этот стандарт стал первым опытом создания единого общего взгляда на программную инженерию. Соответствующий национальный стандарт России – ГОСТ Р ИСО/МЭК 12207-99 [ГОСТ 12207, 1999] содержит полный аутентичный перевод текста международного стандарта ISO/IEC 12207-95 (1995 года).

В свою очередь, IEEE и ACM3, начав совместные работы еще в 1993 году с кодекса этики и профессиональной практики в данной области (ACM/IEEE-CS Code of Ethics and Professional Practice), к 2004 году сформулировали два ключевых описания того, что сегодня мы и называем основами программной инженерии – Software Engineering: - Guide to the Software Engineering Body of Knowledge (SWEBOK), IEEE 2004 Version - Руководство к Своду Знаний по Программной Инженерии, в дальнейшем просто “SWEBOK” [SWEBOK, 2004]; - Software Engineering 2004. Curriculum Guidelines for Undergraduate Degree Programs in Software Engineering – Учебный План для Преподавания Программной Инженерии в ВУЗах1 (данное название на русском языке представлено в вольном смысловом переводе) [SE, 2004].


Оба стандарта стали результатом консенсуса ведущих представителей индустрии и признанных авторитетов в области программной инженерии - по аналогии с тем, как был создан PMI PMBOK. Так мы пришли к сегодняшнему состоянию Software Engineering как дисциплины.

SWEBOK: Руководство к своду знаний по программной инженерии

C 1993 года IEEE и ACM координируют свои работы в рамках специального совместного комитета - Software Engineering Coordinating Committee (SWECC - http://www.computer.org/tab/swecc). Проект SWEBOK был инициирован этим комитетом в 1998 году. Оцененный предположительный объем содержания SWEBOK и другие факторы привели к тому, что было рекомендовано проводить работы по реализации проекта не только силами добровольцев из рядов экспертов индустрии и представителей крупнейших потребителей и производителей программного обеспечения, но и на основе принципа “полной занятости”. Базовый комплекс работ, в соответствии со специальным контрактом, был передан в Software Engineering Management Research Laboratory Университета Квебек в Монреале (Universite du Quebec a Montreal). Среди компаний, поддержавших этот уникальный проект были Boeing, MITRE, Raytheon, SAP. В результате проекта, оcуществленного при финансовой поддержке этих и других компаний и организаций, а также с учетом его значимости для индустрии, SWEBOK Advisory Committee (SWAC) принял решение сделать SWEBOK 2004 trial edition общедоступной. В перспективе, в зависимости от финансирования, SWAC считал необходимым законченную версию SWEBOK (изначально планировалось, что она будет готова в 2008 году) сделать также свободно доступной на Web-сайте проекта – http://www.swebok.org. Сегодняшняя “публичность” (общедоступность) результатов проекта стала возможна, в первую очередь, именно благодаря поддержке SWEBOK Industrial Advisory Board (IAB) – структуры, объединяющей представителей компаний, поддержавших проект.

Проект SWEBOK планировался в виде трех фаз: Strawman (“соломенный человек”), Stoneman (“каменный человек”) и Ironman (“железный человек”). К 2004 году была выпущена версия Руководства по Своду Знаний 3-ей фазы - Ironman, то есть максимально приближенная к окончательному варианту и одобренная IEEE в феврале 2005 года к публикации в качестве Trial-версии. Основная цель текущей “пробной” версии SWEBOK – улучшить представление, целостность и полезность материала руководства на основе сбора и анализа откликов на данную версию с тем, чтобы выпустить финальную редакцию документа в 2008 году. Однако версии 2008 не появилось, хотя ряд дополнений на начало 2010 года и находится уже в виде драфтов, что не исключает расширения SWEBOK в ближайшей перспективе и, в то же время, не принижает значимости уже выпущенной версии 2004.

По ряду обоснованных причин, “SWEBOK является достаточно консервативным” [SWEBOK, 2004, с.B-2]. После 6 лет непосредственных работ над документом, SWEBOK включал “лишь” 10 областей знаний (knowledge areas, KA). При этом, что справедливо и для PMBOK, добавление новых областей знаний в SWEBOK достаточно прозрачно. Все, что для этого необходимо, зрелость (или, по крайней мере, явный и быстрый процесс достижения зрелости) и общепринятость соответствующей области знаний, если это не приведет к серьезному усложнению SWEBOK. (Концепция “общепринятости” - generally accepted – определена в IEEE Std 1490-1998, Adoption of PMI Standard — A Guide to the Project Management Body of Knowledge)

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

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

Структура и содержание SWEBOK

Описание областей знаний в SWEBOK построено по иерархическому принципу, как результат структурной декомпозиции. Такое иерархическое построение обычно насчитывает два-три уровня детализации, принятых для идентификации тех или иных общепризнанных аспектов программной инженерии. При этом, структура декомпозиции областей знаний детализирована только до того уровня, который необходим для понимания природы соответствующих тем и возможности нахождения источников компетенции и других справочных данных и материалов. В принципе, считается, что как таковой “свод знаний” по программной инженерии представлен не в обсуждаемом руководстве (SWEBOK), а в первоисточниках (как указанных в нем, так и представленных за его рамками) [SWEBOK, 2004, с.1-2].

SWEBOK описывает 10 областей знаний:

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

Стоит отметить, что принятые разграничения между областями знаний, их компонентами (subareas) и другими элементами достаточно произвольны. При этом, в отличие от PMBOK, области знаний SWEBOK не включают “входы” и “выходы”. В определенной степени такая декомпозиция связаны с тем, что SWEBOK не ассоциирован с той или иной моделью (например, жизненного цикла) или методом. Хотя на первый взгляд первые пять областей знаний в SWEBOK представлены в традиционной последовательной (каскадной - waterfall) модели, это не более чем следование принятой последовательности освещения соответствующих тем. Остальные области и структура декомпозиции областей представлены в алфавитном порядке.

Для каждой области знаний SWEBOK описывает ключевые акронимы, представляет область в виде “подобластей” (subareas) или как их часто называют в самом SWEBOK – “секций” и дает декомпозицию каждой секции в форме списка тем (topics) с их описанием.

Рисунок 1-а. Первые пять областей знаний SWEBOK на английском языке
Рисунок 1-а. Первые пять областей знаний SWEBOK на английском языке
Рисунок 1-б. Первые пять областей знаний SWEBOK на русском языке
Рисунок 1-б. Первые пять областей знаний SWEBOK на русском языке
Рисунок 2-а. Вторые пять областей знаний SWEBOK на английском языке
Рисунок 2-а. Вторые пять областей знаний SWEBOK на английском языке
Рисунок 2-б. Вторые пять областей знаний SWEBOK на русском языке
Рисунок 2-б. Вторые пять областей знаний SWEBOK на русском языке
Рисунок 3-а. Области знаний связанных дисциплин на английском языке
Рисунок 3-а. Области знаний связанных дисциплин на английском языке
Рисунок 3-б. Области знаний связанных дисциплин на русском языке
Рисунок 3-б. Области знаний связанных дисциплин на русском языке

Перевод SWEBOK на русский язык

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

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

Представленный перевод SWEBOK 2004 никак не заменяет первоисточника и создан Сергеем Орликом при участии Юрия Булуя без какой-либо поддержки IEEE или других структур по собственной инициативе в полном соответствии со SWEBOK Copyright © 2004 by The Institute of Electrical and Electronics Engineers, Inc. All rights reserved. Copyright and Reprint Permissions: This document may be copied, in whole or in part, in any form or by any means, as is, or with alterations, provided that (1) alterations are clearly marked as alterations and (2) this copyright notice is included unmodified in any copy. Далее перевод соответствующих глав SWEBOK включает расширения (замечания и комментарии), помеченные цветом, отличным от цвета перевода оригинального содержания SWEBOK.

Программные требования

Глава базируется на IEEE Guide To The Software Engineering Body Of Knowledge - SWEBOK.

Содержит перевод описания области знаний swebok “software requirements”, с замечаниями и комментариями.

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

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

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

рисунок 1. уровни требований по вигерсу [вигерс, 2003, с.8, рис. 1-1]
рисунок 1. уровни требований по вигерсу [вигерс, 2003, с.8, рис. 1-1]

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

рисунок 2. область знаний “программные требования” [swebok, 2004, с.2-2, рис. 1]
рисунок 2. область знаний “программные требования” [swebok, 2004, с.2-2, рис. 1]

Сама же структура обсуждаемой области знаний в большой степени совместима со стандартами IEEE 12207.x, ISO/IEC, ГОСТ Р ИСО/МЭК 12207. Такая структура построена исходя из идеи выделения ключевых групп вопросов дисциплины.

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

Основы программных требований (Software Requirements Fundamentals)

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

Темы данной секции:

Определение требований (Definition of a Software Requirement)

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

по мнению авторов, необходимо обратить внимание на следующие определения понятия “требование” (на основе работ вигерса и стандарта IEEE Standard Glossary Of Software Engineering Terminology, 1990):

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

Требования к продукту и процессу (Product and Process Requirements)

– проводится разграничение соответствующих требований как свойств продукта, который необходимо получить, и процесса, с помощью которого продукт будет создаваться; отмечается, что ряд требований может быть заложен неявно и программные требования могут порождать требования к процессу, например: работа в режиме 24x7 (как бизнес-требование) наверняка приведет к ограничению выбора тех или иных программных средств, платформ развертывания и архитектурных решений; в свою очередь, выбор платформы j2ee (Java 2 Enterprise Edition) и ее реализации в виде конкретного сервера приложений практически наверняка потребует применения модульного тестирования (Unit Testing) как практики процесса разработки и JUnit, как инструмента реализации этой практики.

Функциональные и нефункциональные требования (Functional and Non-Functional Requirements)

– функциональные требования задают “что” система должна делать; нефункциональные – с соблюдением “каких условий” (например, скорость отклика при выполнении заданной операции); часто функциональные требования представляют в виде сценариев (вариантов использования) use сase.

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

Необходимо сделать несколько важных замечаний по бизнес-правилам. бизнес правила, как таковые, являются предметом пристального изучения различных специалистов в области как бизнес-моделирования, так и программной инженерии в целом. практика разработки программных требований включает идентификацию и описание бизнес-правил как самостоятельных артефактов. например, методология rup выделяет отдельный артефакт business rule в рамках дисциплины business modeling. все бизнес-правила, в рамках данной дисциплины, идентифицируются и описываются в документе business rules document. при разработке требований, в сценариях use cases обычно включается ссылка на уже описанное бизнес-правило. скотт амблер (см. www.agilemodeling.com/artifacts/) так же выделяет бизнес-правило как один из артефактов, который используют в семействе agile методологий.

В настоящее время разработаны методы и подходы формального представления бизнес-правил, вплоть до формальных языков описания (использование ocl – object constraint language, brml – business rules markup language).

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

Рассматривая бизнес-правила, как артефакты относящиеся к области программных требований можно отметить, вернее дать одно из пояснений, почему бп относят к нефункциональным требованиям: например, при написании определенного шага в сценарии use case, используется ссылка на бизнес правило: «… система производит расчет стоимости в соответствии с бизнес-правилом bp41 …». в свою очередь данное бизнес-правило может определять алгоритм расчета стоимости. т.е. налицо «с соблюдением каких условий система делает расчет».

Одним из наиболее известных специалистов по br является рональд росс, автор книги «principles of the business rule approach» (ronald g. ross. «principles of the business rule approach», 2003).

Наравне с представленной классификацией требований, могут использоваться и другие подходы. Даже в рамках этой классификации, существуют и различные взгляды на ее интерпретацию и детализацию. Например, как результат определения целевой аудитории и в рамках маркетинговой стратегии продвижения тиражируемого решения, возможно определять высокоуровневые возможности (ключевые характеристики, особенности) – “фичи” (features) разрабатываемого продукта. Иногда, такие возможности детализируются в смысле функциональных требований в некоторых agile-техниках, например, FDD – Feature-Driven Development (как вы видите вплоть до самого названия целого комплекса практик, метода разработки).

Вигерс, описывает feature как “множество логически связанных функциональных требований, которые предоставляют определенные возможности для пользователя и удовлетворяют бизнес-целям <организации>”. С точки зрения маркетинга программного обеспечения, как отмечает Вигерс, feature это «группа требований, узнаваемая заинтересованными лицами, которые вовлечены в процесс принятия решения по приобретению ПО – это список <отличительных особенностей или возможностей, характеристик>, присутствующий в описании продукта». В то же время, Леффингвелл и Видриг (D.Leffingwell, D. Widrig, Managing Software Requirements: A Use Case Approach, Second Edition, 2003) определяют feature как “сервисы, которые оказывает система для удовлетворения одной или более потребностей заинтересованных лиц (stakeholders needs)”. Ими же отмечается, что в реальных проектах могут быть не определены stakeholders needs (а их часто выделяют, особенно если у проекта/продукта есть много заинтересованных лиц со своими потребностями, и эти потребности могут носить взаимоисключающий характер), но существовать features могут и самостоятельно (как и stakeholder needs), и конечно же возможно существование и stakeholder needs и features со взаимной трассировкой.

Развивая тему features – Kurt Bittner & Ian Spence в своей книге “Use Case Modeling” (Kurt Bittner, Ian Spence. Use Case Modeling, 2002), дают схожее, хотя и более формальное определение features. Они отмечают, что features могут быть как относящимся к функциональным, так и к нефункциональным требованиям. И могут изменяться от версии к версии продукта.

Анализируя различные источники на предмет работы с features, следует отметить следующее:

С точки зрения инженерии требований, features являются самостоятельным артефактом, который может быть соотнесен как с функциональными требованиями, так и с нефункциональными (в т.ч. с ограничениями проектирования или атрибутами качества).

Необходимо также отметить, что Features обладают определенным дуализмом в своей интерпретации, зависимым от контекста конкретного продукта – с одной стороны это может быть «тот самый список характеристик, указанный на коробке продукта» в случае создания «коробочного ПО», с другой стороны это может список высокоуровневых возможностей системы, например при заказной разработке ПО автоматизации бизнес-процессов конкретной организации.

Features могут быть разного уровня детализации – от выражения высокоуровневых возможностей системы (например, «Расчет заработной платы …»), до достаточно конкретных требований (например, «Автоматическое уведомление Клиента по e-mail о резервировании товара на складе»)

Независимые или общие свойства (Emergent Properties)

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

Требования с количественной оценкой (Quantifiable Requirements)

– требования, поддающиеся количественному определению/измерению, например, система должна обеспечить пропускную способность “столько-то запросов в секунду”; в то же самое время, крайне важно понимать, что постановка вопроса (то есть формулирование требования) в форме “система должна обеспечить рост пропускной способности” без указания конкретных количественных характеристик является просто некорректно определенным требованием.

При этом, например, требование “система должна вести журнал подключений пользователей” может и должно детализироваться с точки зрения описания информации, которую необходимо сохранять в журнале, однако, такое требование уже не будет являться количественным требованием. А требование с формулировкой “система должна обладать интуитивно-понятным пользовательским интерфейсом” - непроверяем. В определенных случаях, по мнению автора книги, это может выглядеть просто издевкой, даже не являясь изначально таковой – все зависит от точки зрения: например, в устах “целевого” пользователя специализированного программного обеспечения – системного администратора, привыкшего работать в kshell (популярной командной оболочке Unix/Linux), объясняющего свои потребности аналитику, фиксирующему запросы пользователя и привыкшего оперировать Microsoft Office ;) Может ли такое требование быть переформулировано и/или детализировано для адекватности интерпретации? Да. Например, так – средний показатель ошибок оператора не должен превышать 2% от объема вводимой информации и 85% пользователей должны дать положительную оценку прототипу пользовательского интерфейса на этапе опытной эксплуатации.

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

Большинство требований с количественной оценкой относится к атрибутам качества.

В качестве примера можно привести реальное требование, присутствующее в реальном проекте по электронному документообороту: “Система должна производить поиск документов <определенного вида> за время, не превышающее 5 секунд”. Это типичное требование с количественной оценкой, в котором определена верхняя граница диапазона времени, за которое должен быть осуществлен поиск документов. Несомненно, этот атрибут качества системы существует в контексте определенного функционального требования о возможности поиска документов по определенным критериям. И этот контекст или связь должна быть определена либо явно, в рамках иерархии требований, либо посредством трассировки, между требованиями разных видов (функционального и атрибута качества). Примечательно, что Вигерс в своей книге выделяет требования по производительности системы в отдельный вид требований, тем не менее входящих в понятие нефункциональных требований или атрибутов качества.

Системные требования и программные требования (System Requirements and Software Requirements)

– данное разделение базируется на определении “системы”, данном INCOSE (International Council on Systems Engineering) “комбинация взаимодействующих элементов <созданная> для достижения определенных целей; может включать аппаратные средства, программное обеспечение, встроенное ПО, другие средства, людей, информацию, техники (подходы), службы и другие поддерживающие элементы”; таким образом, подразумевается, что система является более ёмким понятием, чем программное обеспечения и включает окружение, в котором функционирует ПО, как таковое; отсюда, естественным образом, вытекают требования к системе в целом и программному обеспечению (или программной системе), в частности. Часто в литературе по управлению требованиями встречается описание системных требований как “пользовательских требований” (user requirements), SWEBOK ограничивает применение понятия “пользовательское требование” требованиями к системе конечных пользователей/заказчиков. Системные требования по SWEBOK, в свою очередь, окружают пользовательские требования (или требования других заинтересованных лиц – stakeholders, например, регулирование полномочий) без указания идентифицируемого источника-человека.

Процесс работы с требованиями (Requirements Process)

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

Цель данной темы, в соответствии с SWEBOK, дать понимание того, что такое процесс работы с требованиями, как таковой. В русском языке также устойчиво используется его название как “процесс определения требований”. мы его будем использовать взаимозаменяемым образом, подразумевая весь процесс работы с требованиями по SWEBOK.

Что ж, рассмотрим структуру декомпозиции тем процесса работы с требованиями:

Модель процесса определения требований:

В частности, тема процесса определения требований касается тех вопросов, которые охватываются в рамках сбора, анализа, специфицирования и утверждения требований ч точки зрения организации этих видов деятельности для различных типов проектов и значимости тех или иных ограничений по отношению к процессу. В большинстве случаев, процесс определения, работы с требованиями выделен в самостоятельный набор и описан как последовательность (сценарии) действий, связанных с ними ролей и непосредственных результатов (их часто называют “артефактами”, например, в RUP – Rational Unified Process), в рамках конкретных методологий разработки программного обеспечения, наиболее популярные из которых мы рассмотрим позднее.

Участники процессов (Process Actors)

В этой теме вводится понятие “роли” и дается понимание “ролей” для людей, которые участвуют в процессе работы с требованиями (чувствуете отличие между “определением” требований и “работой” с ними?). Таких людей также называют “заинтересованными лицами” (в данном контексте - software stakeholders). Заинтересованное лицо – некто, имеющий возможность (в том числе, материальную) повлиять на реализацию проекта/продукта.

Типичные примеры ролей:

Стандарт 12207 (его обзор будет приведен в другой главе) определяет более суженное понятие “заказчика” (обратите внимание – acquirer, а не customer, хотя часто оба термина переводятся на русский язык одинаково) как организацию, которая приобретает или получает систему, программный продукт или программную услугу от поставщика. Здесь возможно использовать такое общее определение: заказчик – лицо или организация, получающие прямую или косвенную выгоду от использования продукта. Клиентами считают тех заинтересованных лиц, кто требует, оплачивает, выбирает, использует или получает результаты работы программного обеспечения. В этом плане, “заказчик” в понимании стандарта 12207 скорее ближе к “клиенту” в такой интерпретации.

SWEBOK особо подчеркивает, что если невозможно в точности (в оригинале – “perfectly”) удовлетворить требования каждого заинтересованного лица, именно работа инженера включает проведение переговоров и поиск компромисса, приемлемого для ключевых заинтересованных лиц (“стейкхолдеров”) и удовлетворяющего бюджетным, техническим, временным и другим ограничениям проекта. Необходимо понимать, что такая деятельность практически наверняка приведет к изменениям в требованиях, как минимум, на уровне соответствующих приоритетов требований и, следовательно, работ по их реализации.

Управление и поддержка процессов (Process Support and Management)

Эта тема затрагивает вопросы распределения ресурсов, необходимых для осуществления проектной деятельности, устанавливая контекст для первой секции “Инициация и определение содержания” (Initiation and Scope Definition) области знаний “Управление в программной инженерии” (Software Engineering Management). Основная цель данной темы – обеспечение связи между процессами и деятельностью, определенными в 2.1 “модели процесса определения требований” и вопросами использования проектных ресурсов – стоимостью, человеческими ресурсами, инструментами и т.п.

Качество и улучшение процессов (Process Quality and Improvement)

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

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

Улучшение процессов и в частности процессов разработки и управления требованиями должно предваряться формулировкой проблемы. Т.е. нет смысла заниматься улучшением ради улучшения, нужно четко понимать какая в настоящее время есть проблема в работе с требованиями, и насколько эта проблема значима, и только потом приступать к ее устранению, в частности через улучшение процессов. Реальная отечественная практика многих организаций, занимающихся разработкой ПО, показывает, что очень немногие имеют действительно четкое представление о том, каким образом организация работы с требованиям может повлиять на успех компании в целом. Обычно, отечественные компании, в лучшем случае просто документируют требования, выпуская документы, например, Техническое задание по ГОСТ. Но действительно ли в этом документе можно увидеть требования – увы. Следуя только рекомендациям, которые есть в ГОСТ можно только соответствующим образом оформить разделы, что практически никак не влияет на качество и информативность документа. Вопросы совершенствования процессов – process improvement будут рассматриваться как в главах, посвященных CMMI, так и в других частях этой книги.

Данная тема тесно связана с областями знаний “Качество программного обеспечения” (Software Quality) и “Процесс программной инженерии” (Software Engineering Process). В этом контексте, фокусы обсуждаемой темы – определение атрибутов и метрик качества, а также определение соответствующих процессов в применении к программным требованиям, которые можно свести в три группы практик:

Извлечение требований (Requirements Elicitation)

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

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

Источники требований (Requirement Sources)

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

Тема фокусируется на:

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

Техники извлечения требований (Elicitation Techniques)

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

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

Существуют и другие, достаточно эффективные практики, описание которых можно найти в литературе и которые вы, наверняка, сами используете в своей работе (например, Requirements Workshop, Role Playing, Storyboarding и т.п.). Некоторые из них будут также упоминаться в контексте конкретных методологий.

Анализ требований (Requirements Analysis)

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

Анализ требований включает:

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

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

Классификация требований (Requirements Classification)

Требования могут классифицироваться по целому ряду параметров, например:

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

Концептуальное моделирование (Conceptual Modeling)

Разработка модели проблемы реального мира – ключевой элемент анализа требований. Цель моделирования – понимание проблемы, задачи и методов их решения до того, как начнется решение проблемы.

Часто приходится слышать, что прагматичность подхода в отношении программных проектов заключается в “пропуске” этапа (или стадии, фазы) моделирования. В свою очередь, часто ставят знак равенства между моделированием и “этими красивыми квадратиками со стрелочками”. Ни то, ни другое утверждение неверны. Например, в XP и в других гибких (Agile) практиках существуют и истории пользователей, и карточки задач, и процедуры анализа (в частности, связанных с ними “мозговых штурмов”, как запланированных, так и, к сожалению, не очень) , в результате которого мы сформулировали задачи, высокоуровневые возможности - “фичи” продукта (feature - особенность), а также необходимые модели (см. [Амблер, 2002]). Объем моделей, их детализация и средства представления могут быть различны. Их выбор базируется и/или диктуется конкретным культурным контекстом организаций, вовлеченных в проект, и практик, применяемых проектной группой. Именно не форма, но сама идея моделирования как попытка упростить и однозначно интерпретировать на концептуальном уровне проблематику деятельности в реальном мире – обязательная составляющая как управления требованиями, так и программной инженерии, в целом.

Среди факторов, которые влияют на выбор модели, метода и детализации ее представления, степени связанности с программным кодом и другими вопросами:

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

Вопросы моделирования тесно связаны с применяемыми методами и подходами. Однако, частные методы или нотации, как отмечается в SWEBOK, так или иначе следуют распространенным в индустрии практикам и тяготеют к тем формам, с которыми связаны накопленный опыт и подтвержденные общепринятой практикой знания. SWEBOK отмечает, что могут быть разработаны различные виды моделей, включающие потоки работ и данных, модели состояний, трассировки событий, взаимодействия пользователей, объектные модели, модели структур данных, и т.п. Кстати, именно такая ситуация сложилась с UML, все чаще воcпринимаемым в качестве общепринятого или de-facto стандарта в моделировании и включающем целый комплекс моделей (в UML 2.0 включено 14 моделей, представленные в двух группах – статические модели и поведенческие), связанных и объединенных общей архитектурой, на основе концепции метамоделей.

Cовременное состояние стандарта UML (унифицированного языка моделирования Unified Modeling Language, разрабатываемого консорциумом OMG – www.omg.org ) версии 2.0 вполне позволяет говорить о расширении его применимости в “чистом” бизнес-моделировании. На фоне богатства выразительных средств, появления соответствующего инструментального обеспечения работы с UML 2.0, длительной истории успешного применения стандарта UML 1.x, инструментов на его основе и повсеместного использования UML в области объектно-ориентированного анализа и проектирования не только аналитиками, но архитекторами и разработчиками ПО, можно с уверенностью говорить о смещении фокуса индустрии программного обеспечения в сторону UML и отходу (как минимум, частичному) от IDEF, в применении к аналитической деятельности. Темпы такой “миграции”, конечно, зависят от степени консервативности взглядов конкретных специалистов-аналитиков. Однако, давление рынка, требование унификации, в частности, выразительных средств описания активов проектов в рамках всей проектной команды – те причины, по которым, по мнению автора, аналитики, не воспринявшие UML-ориентированный тренд, могут оказаться за бортом серьезных корпоративных ИТ-проектов. Даже на фоне “неприятия” UML некоторыми игроками рынка, критическая масса знаний и практик по его применению уже оказалась достаточно велика, чтобы игнорировать его применение. В то же самое время, не стоит воспринимать UML как панацею – это касается любой технологии, практики или подхода. Создан, активно развивается и уже поддержан индустрией стандарт BPMN – Business Process Management Notation (см. www.bpmi.org). Таким образом, все определяется конкретным “культурным” контекстом. Просто надо помнить об этом и оставаться “прагматиками”, в положительном понимании этого слова, не теряя креативности в повседневной деятельности.

Необходимо отметить, что на практике наблюдается тенденция разделения вопросов определения требований и моделирования. Это, например, заметно в современных методологиях, таких как RUP (Rational Unified Process), где работа с требованиями и моделирование/проектирование – суть две разные дисциплины.

Архитектурное проектирование и распределение требований (Architectural Design and Requirements Allocation)

Считается, что создание архитектуры программных решений является обязательным элементов успешности таких проектов. Архитектурное проектирование перекрывается с программным и системным дизайном (проектированием) и иллюстрирует насколько сложно провести четкую грань между различными аспектами проектирования. Данная тема работы с программными требованиями тесно связана с секцией “Структура и архитектура программного обеспечения” (Software Structure and Architecture) области знаний “Проектирование программного обеспечения” (Software Design). Во многих случаях, инженеры действуют как архитекторы, потому как процессы анализа и выработки требований зависят от программных компонент, создаваемых для решения поставленных заданными требованиями задач, призванных, в конечном счете, добиться реализации поставленных перед проектом целей.

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

Существует ряд стандартов и общепринятых практик, связанных с архитектурным проектированием. Среди них наиболее популярны:

Важно заметить, что ни в коем случае не надо путать архитектурные рекомендации (Architectural Guidelines) с практиками и стандартами архитектурного проектирования. Одни (например, Federal Enterprise Architecture Framework FEAF) дают рекомендации по конкретным архитектурно-технологическим решениям. Другие концентрируются именно на том, чему стоит уделить внимание при создании архитектуры, как ее описать и детализировать, и что из себя представляет архитектура, как таковая (например, ISO 15704 Industrial Automation Systems – Requirements for Enterprise-Reference Architectures and Methodologies).

Спецификация требований (Requirements Specification)

На инженерном жаргоне, да и в терминологии ряда методологий, устоялся термин “software requirements specification” (SRS) – спецификация программных требований. Для сложных систем, на самом деле, существует целый комплекс спецификаций, документов, которые являются результатом сбора и анализа требований, их моделирования и архитектурного проектирования. Эти документы систематически анализируются, в них вносятся изменения, они пересматриваются и утверждаются. Чаще всего, для описания комплексных проектов (в части требований) используется три основных документа (спецификации):

Определение системы (System Definition Document)

Данный документ, часто называемый как “спецификация пользовательских требований” (user requirements specification) или “концепция” (concept ), описывает системные требования. Содержание документа определяет высокоуровневые требования, часто – стратегические цели, для достижения которых создается программная система. Принципиальным моментом является то, что такой документ описывает требования к системе с точки зрения области применения - “домена”. Соответственно, изложение требований в нем ведется в терминах прикладной области. Документ описывает системные требования вместе с необходимой информацией о бизнес-процессах, операционном окружении с точки зрения бизнес-процедур и организационных и других регламентов. Примером стандарта для создания и структурирования такого документа является IEEE 1362 “Concept of Operations Document”.

Спецификация системных требований (System Requirements Specification)

В сложных проектах принято разделять спецификацию системных требований (system requirements) и спецификацию программных требований (software requirements). При таком подходе программные требования порождаются системными требованиями и детализируют требования к компонентам и подсистемам программного обеспечения. Документ описывает программную систему в контексте системной инженерии (system engineering), идеи которой кратко описаны в Главе 12 SWEBOK “Связанные дисциплины программной инженерии”. Строго говоря, спецификация системных требований описывает деятельность системных инженеров и выходит за рамки обсуждения SWEBOK. Стандарт IEEE 1233 является одним из признанных руководств по разработке системных требований. И, как уже отмечалось ранее, не стоит забывать о том, что понятие система, в общем случае, охватывает программное обеспечение, аппаратную часть и людей. Системная инженерия (см. материалы INCOSE – www.incose.org ), в свою очередь, самостоятельная и не менее объемная дисциплина чем программная инженерия. SWEBOK рассматривает системную инженерию как важную связанную дисциплину. Ну а системные требования – один из элементов реального связывания различной инженерной деятельности - программной и системной.

Спецификация программных требований (Software Requirements Specification - SRS)

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

Программные требования устанавливают основные соглашения между пользователями (заказчиками) и разработчиками (исполнителями) в отношении того, что будет делать система и чего от нее не стоит ожидать. Документ может включать процедуры проверки получаемого программного обеспечения на соответствие предъявляемым ему требованиям (вплоть до содержания планов тестирования), характеристики, определяющие качество и методы его оценки, вопросы безопасности и многое другое. Часто программные требования описываются на обычном языке. В то же время, существуют полуформальные и формальные методы и подходы, используемые для спецификации программных требований. В любом случае, задача состоит в том, чтобы программные требования были ясны, связи между ними прозрачны, а содержание данной спецификации не допускало разночтений и интерпретаций, способных привести к созданию программного продукта, не отвечающего потребностям заинтересованных лиц. Стандарт IEEE 830 является классическим примером стандарта на содержание структурирование и методы описания программных требований – “Recommended Practice for Software Requirements Specifications”.

Необходим отметить, что в документацию на требования не следует вносить элементы дизайна системы (скажем, логическую модель базы данных). А вот сценарии использования Use Case часто включают в спецификацию требований наравне с трассировкой (traces) к соответствующим моделям в форме диаграмм, например, к UML Use Case, UML Activity, BPMN и т.п. . Говоря о написании спецификаций требований, то есть одно серьезное заблуждение, которое делают обычно неопытные аналитики – это фактическая подмена требований как таковых, моделями графического пользовательского интерфейса, т.е. когда в документы-спецификации требований просто включаются «картинки» пользовательского интерфейса с небольшими пояснениям. Это отнюдь не означает, что с заинтересованными лицами и в частности с пользователями, не следует вообще обсуждать дизайн GUI, часто это имеет смысл делать, но для этого существует, например, прототипирование. Мне довелось изучить многие документы требований в разных организациях и практически все они имели одни и те же проблемы:

Проверка требований (Requirements Validation)

Определение требований напрямую связано с процедурами проверки (verification) и утверждения (аттестации - validation, как это сформулировано в ГОСТ Р и ISO/IEC 12207). Вообще говоря, принято считать, что требования описаны неполностью, если для них не заданы правила V&V (verification&validation – проверка и аттестация), то есть не определены способы проверки и утверждения. Процедуры проверки являются отправной точкой для инженеров-тестировщиков и специалистов по качеству, непосредственно отвечающих за соответствие получаемого программного продукта предъявляемым к нему требованиям.

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

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

Для достижения этой цели применяется ряд практик, в том числе, представленных ниже.

Обзор требований (Requirements Review)

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

Вопросы обзора требований, вообще говоря, имеют непосредственное отношение к теме качества, поэтому они также описываются в области знаний SWEBOK “Качество программного обеспечения” (Software Quality) в теме 2.3 “Обзор и аудит” (Review and Audit).

Прототипирование (Prototyping)

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

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

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

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

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

Утверждение модели (Model Validation)

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

Приемочные тесты (Acceptance Tests)

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

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

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

Дополнительная информация, связанная с приемочными тестами представлена в области знаний SWEBOK “Тестирование программного обеспечения” (Software Testing) в описании 2.2.4 “Тесты соответствия” (Conformance testing).

Практические соображения (Practical Considerations)

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

Далеко не каждая организация обладает культурой документирования и управления требованиями. Особенно часто это встречается в молодых небольших компаниях, выводящих на рынок новые продукты и обладающие “сильным вижином”, четким пониманием целей, для которых создается продукт, но не имеющих достаточно ресурсов и, во многом поэтому считающих, что динамизм – залог успеха. Постепенно такие компании вырастают, проекты – усложняются и, как следствие складывается ситуация, когда отследить все необходимые требования в неформальной форме уже просто невозможно. Эта тема практически неисчерпаема. Многие средние по масштабам компании пытаются сохранить тот же вровень гибкости и динамизма, который применялся во времена рождения компании, когда она еще была “стартапом” (start-up – название молодых компаний, которые раскручивали свои проекты во времена интернет-бума конца 90-х и которое прижилось для вновь образующихся малых бизнесов, растущих не столько на внешних инвестициях, сколько на идеях и упорстве ее создателей). Так или иначе, динамизм присущ не только компаниям, но и продуктам, самим требованиям к ним. Управление изменениями, концепцией, видением продукта не может быть хаотическим – история индустрии однозначно это показывает. Поэтому отношение к управлению требованиями как к постоянно действующему бизнес-процессу – абсолютно обоснованный подход, требующий применения определенных практик. В противном случае, мы практически гарантировано столкнемся с темни негативными последствиями, которые не раз описывались и упоминались выше.

Итеративная природа процесса работы с требованиями (Iterative Nature of the Requirements Process)

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

Управление изменениями (Change Management)

Управление изменениями – одна из ключевых тем управления требованиями. Необходимость определения процедур для обработки изменений совсем не то же самое, что и их детальная формализация. Такие процедуры необходимы. Им посвящена тема управления изменениями в приложении к требованиям. В то же время, рассматривать изменение требований в отрыве от других процессов, по меньшей мере, кажется странным. Соответственно, данный вопрос является составной частью управления изменениями и конфигурациями программного обеспечения (Software Configuration and Change Management, SCCM), которое сегодня принято называть просто конфигурационным управлением (Software Configuration Management, SCM), подразумевая, что это не только вопросы контроля версий, но управление всеми активами проекта, включая код, требования, запросы на изменения – change requests (в том числе, отчеты об ошибках – defect или bug reports), задачи (в терминах проектного менеджмента) и т.п.

Общий комплекс вопросов конфигурационного управления рассматривается в области знаний SWEBOK “Управление конфигурациями программного обеспечения” (Software Configuration Management).

Атрибуты требований (Requirements Attributes)

Требования должны состоять не только из описания того, что необходимо сделать, но и содержать информацию, необходимую для интерпретации требований и управления ими. Например, с пользовательскими требованиями часто ассоциируют сценарии Use Case (как в текстовом, так и графическом представлении) и, в то же время, функциональные требования часто трансформируются в задачи в терминах проектного управления, с которыми связаны параметры законченности (например, в процентах), ответственности (например, кто является “владельцем” требования, кто из инженеров назначается исполнителем или принимает на себя обязанности, связанные с реализацией заданной функциональности, как это принято, например, в XP или FDD). Примеров существует множество и, в зависимости от применяемых практик и методов, сложившейся проектной и организационной культуры, спектр атрибутов может меняться достаточно широко, практически, неограниченно.

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

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

Трассировка требований (Requirements Tracing)

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

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

Измерение требований (Measuring Requirements)

С практической точки зрения, обычно полезно иметь нечто, позволяющее определить “объем” требований для заданного (создаваемого) программного продукта. Это число полезно для исследования “масштабов” изменений в требованиях, оценки стоимостных характеристик (cost estimation) разработки и поддержки программной системы, опосредовано – оценки продуктивности разработки и эффективности поддержки на этапах реализации требований и внесения изменений и т.п.

Измерение объема функциональности (Functional Size Measurement, FSM) техника такого рода численной оценки, определена на концептуальном уровне в стандарте IEEE 14143.1. Стандарты ISO/IEC и другие источники описывают частные методы FSM (например, модель COCOMO II для оценки стоимости, например, может использоваться в тесной связи с методами функциональных точек – functional points для оценки масштабов функциональности, то есть требований, предъявляемых заданной программной системе).

Дополнительная информация по стандартам и подходам в оценке масштабов представлена в области знаний “Процесс программной инженерии” (Software Engineering Process).

В дополнение к практическим соображениям, представленным в SWEBOK, на фоне общей тенденции разработки моделей <оценки> зрелости, стоит отметить, что существуют определенные работы и по созданию различных моделей зрелости требований. Например, наиболее популярная модель зрелости в индустрии программного обеспечения – CMMI включает разный объем и содержание работ по определению и управлению требованиями для уровней зрелости 2 и 3.

Проектирование программного обеспечения

Глава базируется на IEEE Guide to the Software Engineering Body of Knowledge - SWEBOK.

Содержит перевод описания области знаний SWEBOK “Software Design”, с замечаниями и комментариями.

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

Проектирование играет важную роль в процессах жизненного цикла создания программного обеспечения (Software Development Life Cycle), например, IEEE и ISO/IEC (ГОСТ Р ИСО.МЭК) 12207. Проектирование программных систем можно рассматривать как деятельность, результат которой состоит из двух составных частей:

В результате консенсуса, принятого создателями SWEBOK, данная область знаний не описывает все сущности или понятия, имеющие в своем названии слово “дизайн” или “архитектура”. В 1999 году Том ДеМарко (Tom DeMarco) [DeMarco, 1999], один из известных специалистов в программной инженерии, предложил терминологическое разделение различных видов дизайна:

Если обсуждать данную область знаний в терминах ДеМарко, проектирование программного обеспечения в понимании программной инженерии подразумевает D- и FP-дизайн. I-дизайн в большей степени относится к работе с программными требованиями.

Соответственно, данная область знаний тесно связана со следующими областями программной инженерии:

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

Рисунок 3. Область знаний “Проектирование программного обеспечения” [SWEBOK, 2004, с.3-2, рис. 1]
Рисунок 3. Область знаний “Проектирование программного обеспечения” [SWEBOK, 2004, с.3-2, рис. 1]

Основы проектирования (Software Design Fundamentals)

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

Темы данной секции:

Общие концепции проектирования (General Design Concepts)

К ним относятся: цель архитектуры, ее ограничения, возможные альтернативы, используемые представления и решения. Например, архитектурный фреймворк – TOGAF [TOGAF, 2003], разработанный и развиваемый консорциумом The Open Group (www.opengroup.org), предлагает следующие <возможные> цели (goals):

Контекст проектирования (Context of Software Design)

Для понимания роли проектирования программного обеспечения важно понимать контекст, в котором осуществляется проектирование и используются его результаты. В качестве такого контекста выступает жизненный цикл программной инженерии, а проектирование напрямую связано с результатами анализа требований, конструированием программных систем и их тестированием. Стандарты жизненного цикла, например, IEEE и ISO/IEC (ГОСТ Р) 12207 уделяют специальное внимание вопросам проектирования и детализируют их, описывая контекст проектирования – от требований до тестов.

Процесс проектирования (Software Design Process)

Проектирование в основном рассматривается как двух-шаговый процесс:

Архитектурное проектирование – декомпозиция структуры (статической) и организации (динамической) компонент;

Детализация архитектуры – описывает специфическое поведение и характеристики отдельных компонент.

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

Техники применения (Enabling Techniques)

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

Абстракция (Abstraction)

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

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

Связанность и соединение (Coupling and Cohesion)

Связанность (Coupling) – определяет силу связи (часто, взаимного влияния) между модулями. Соединение (Cohesion) – определяет как тот или иной элемент обеспечивает связь внутри модуля, внутреннюю связь.

Значение оригинальных терминов очень близко и, в зависимости от контекста, “связанность” и “соединение” могут рассматриваться как степень самодостаточности или ее отсутствия (coupling) и функциональная зависимость (cohesion) , соответственно.

Хочется особенно подчеркнуть значимость этих понятий, так как с развитием сервисно-ориентированной архитектуры (Service-Oriented Architecture, SOA), слабосвязанной по своей природе (то есть со слабым “сопряжением”, слабой “силой связи” между модулями), по сравнению, например, с OMG CORBA (Common Object Request Broker Architecture), все чаще приходится сравнивать различные подходы и решения, определяемые способом и степенью связанности различных модулей, компонент и самих программных систем.

Декомпозиция и разбиение на модули (Decomposition and Modularization)

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

Инкапсуляция/сокрытие информации (Encapsulation/information hiding)

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

Разделение интерфейса и реализации (Separation of interface and implementation)

Данная техника предполагает определение компонента через специфицирование интерфейса, известного (описанного) и доступного клиентам (или другим компонентам), от непосредственных деталей реализации.

Достаточность, полнота и простота (Sufficiency, completeness and primitiviness)

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

Данный принцип особенно ярко выделен и явно представлен в виде рекомендуемых практик (best practices) методологий гибкого моделирования и экстремального программирования, где “все, что надо, но ни граммом больше” лежит в основе самой концепции “прагматичного” подхода (и на стадии моделирования, и в отношении реализации в коде). В оригинале этот принцип звучит как YAGNI – “You Aren’ t Going to Need It”, то есть “не делай этого, пока не понадобится”.

Ключевые вопросы проектирования (Key Issues in Software Design)

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

Параллелизм (Concurrency)

Эта тема охватывает вопросы, подходы и методы организации процессов, задач и потоков для обеспечения эффективности, атомарности, синхронизации и распределения (по времени) обработки информации.

Контроль и обработка событий (Control and Handling of Events)

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

Распределение компонентов (Distribution of Components)

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

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

Обработка ошибок и исключительных ситуаций и обеспечение отказоустойчивости (Errors and Exception Handling and Fault Tolerance)

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

Взаимодействие и представление (Interaction and Presentation)

Тема касается вопросов представления информации пользователям и взаимодействия пользователей с системой, с точки зрения реакции системы на действия пользователей. Речь в этой теме идет о реакции системы в ответ на действия пользователей и организации ее отклика с точки зрения внутренней организации взаимодействия, например, в рамках популярной концепции Model-View-Controller.

Ни в коем случае не надо путать данную тему с вопросами организации пользовательского интерфейса, являющимеся частью “Эргономики программного обеспечения” – Software Ergonomics (см. “Связанные дисциплины”).

Сохраняемость данных (Data Persistence)

Именно сохраняемость, а не сохранность, так как тема касается не доступа к базам данных, как такового, а также не гарантий сохранности информации. Суть вопроса – как должны обрабатываться “долгоживущие” данные.

Структура и архитектура программного обеспечения (Software Structure and Architecture)

В строгом значении архитектура программного обеспечения (software architecture) – описание подсистем и компонент программной системы, а также связей между ними. Архитектура пытается определить внутреннюю структуру получаемой системы, задавая способ, которым система организована или конструируется.

В середине 90-х, на волне распространения клиент-серверного подхода и начала его трансформации в “многозвенный клиент-сервер”, призванный обеспечить централизованное развертывание и управление общей (для клиентских приложений) бизнес-логикой, вопросы организации архитектуры программного обеспечения стали складываться в самостоятельную и достаточно обширную дисциплину. В результате, сформировалась точка зрения на архитектуру не только в приложении к конкретной программной системе, но и развился взгляд на архитектуру, как на приложение общих (generic) принципов организации программных компонент. В итоге, уже на сегодняшний день, на фоне такого развития понимания архитектуры, накоплен целый комплекс подходов и созданы (и продолжают создаваться и развиваться !) различные архитектурные “фреймворки”, то есть систематизированные комплексы методов, практик и инструментов, призванные в той или иной степени формализовать имеющийся в индустрии опыт (как положительный – например, design patterns, так и отрицательный – например, anti-patterns). Примеры такой систематизации в форме фреймворков:

Архитектурные структуры и точки зрения (Architectural Structures and Viewpoints)

Любая система может рассматриваться с разных точек зрения – например, поведенческой (динамической), структурной (статической), логической (удовлетворение функциональным требованиям), физической (распределенность), реализации (как детали архитектуры представляются в коде) и т.п. В результате, мы получаем различные архитектурные представления (view). Архитектурное представление может быть определено, как частные аспекты программной архитектуры, рассматривающие специфические свойства программной системы. В свою очередь, дизайн системы – комплекс архитектурных представлений, достаточный для реализации системы и удовлетворения требований, предъявляемых к системе.

SWEBOK не дает явного определения, что такое “архитектурная структура”. В то же время это понятие достаточно важно. Я хотел бы предложить его толкование как применение архитектурной точки зрения и представления к конкретной системе и описания тех деталей, которые необходимы для реализации системы, но отсутствуют (в силу достаточно общего взгляда) в используемом представлении. Таким образом, представление (view), концентрируясь на заданном подмножестве свойств является составной частью и/или результатом точки зрения, а архитектурная структура – дальнейшей детализацией в отношении проектируемой системы.

Модель Захмана [Zachman] является великолепным и, кстати, классическим источником комплекса архитектурных точек зрения и представлений, построенных в системе координат “вопрос-уровень детализации”. Каждое архитектурное представление является результатом ответа на вопрос (Как? Что? Где? и т.п.) в контексте необходимого уровня абстракции (содержание, то есть концепция: бизнес-модель, то есть функциональность и т.д.). Например, физическая модель данных (Physical Data Model) является ответом на вопрос “что?” в контексте технологической модели, а логическая модель данных, отвечая на тот же вопрос, находится на один уровень абстракции выше – в контексте системной или логической модели.

Архитектурные стили (Architectural Styles)

В рассматриваемой редакции SWEBOK допущено несоответствие между структурой декомпозиции данной области знаний и описанием охватываемых ею тем. Если архитектурные стили присутствуют в декомпозиции, в самом описании области знаний темы 3.1 и 3.2 смешаны (по форматированию и структуре) в рамках темы “3.1”, (о чем сообщено ассоциированному редактору данной части SWEBOK).

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

Шаблоны проектирования (Design Patterns)

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

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

Чаще всего говорят о следующих группах шаблонов проектирования:

В SWEBOK данная тема, в силу упомянутого выше несоответствия между структурной декомпозицией и описанием области знаний “проектирование”, имеет номер 3.2 (следующая тема, в свою очередь, представлена в SWEBOK как 3.3).

Семейства программ и фреймворков (Families of Programs and Frameworks)

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

Анализ качества и оценка программного дизайна (Software Design Quality Analysis and Evaluation)

Атрибуты качества (Quality Attributes)

Существует целый спектр различных атрибутов, помогающих оценить и добиться качественного дизайна. Эти атрибуты могут описывать многие характеристики системы и элементов дизайна как такового – “тестируемость”, “переносимость”, “модифицируемость”, “производительность”, “безопасность” и т.п.

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

Необходимо понимать, что существуют атрибуты, которые сложно измерить. Например, портируемость или безопасность. Не стоит путать атрибуты качества дизайна с атрибутами качества, фигурируемыми в ряду требований, предъявляемых к системе. Часть из них может отображаться друг на друга и нести эквивалентную смысловую нагрузку, некоторые могут быть связаны, большая часть атрибутов является специфичной именно для дизайна и не связана с требованиями. Например, если мы используем платформу J2EE (Java 2 Enterprise Edition) и ориентируемся на использование компонентой модели EJB (Enterprise JavaBeans), существуют признаки хорошего дизайна, специфичные для данной платформы и компонентной модели, но абсолютно никак не связанные с какими-либо требованиями к создаваемой на этой платформе программной системе. Если вернуться к измеряемым атрибутам качества, они описываются определенными метриками. Приведенный выше пример с количеством бизнес-методов на класс является метрикой, относящейся к теме 4.3 “Измерения”. Эта же метрика позволяет оценить атрибуты качества “модифицируемость” и “сложность” системы.

Анализ качества и техники оценки (Quality Analysis and Evaluation Techniques)

В индустрии распространены многие инструменты, техники и практики, помогающие добиться качественного дизайна:

Измерения (Measures)

Также известные как метрики. Могут быть использованы для количественной оценки ожиданий в отношении различных аспектов конкретного дизайна, например, размера <проекта>, структуры (ее сложности) или качества (например, в контексте требований, предъявляемых к производительности). Чаще всего, все метрики разделяют по двум категориям:

Нотации проектирования (Software Design Notations)

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

Определенные нотации используются на стадии концептуального проектирования, ряд нотаций ориентирован на создание детального дизайна, многие могут использоваться на обеих стадиях. Кроме того, нотации чаще всего используют в контексте (выбор нотации может быть обусловлен таким контекстом) применяемой методологии или подхода (см. 6 “Software Design Strategies and Methods” данной области знаний). Ниже мы будем рассматривать нотации, исходя из описания структурного (статического) или поведенческого (динамического) представления.

Структурные описания, статический взгляд (Structural Descriptions, static view)

Следующие нотации, в основном (но, не всегда), являются графическими, описывая и представляя структурные аспекты программного дизайна. Чаще всего они касаются основных компонент и связей между ними (статических связей, например, таких как отношения “один-ко-многим”).

Поведенческие описания, динамический взгляд (Behavioral Descriptions, dynamic view)

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

Стратегии и методы проектирования программного обеспечения (Software Design Startegies and Methods)

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

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

Общие стратегии (General Strategies)

Это обычно часто упоминаемые и общепринятые стратегии:

Функционально-ориентированное или структурное проектирование (Function-Oriented – Structured Design)

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

Объектно-ориентированное проектирование (Object-Oriented Design)

Представляет собой множество методов проектирования, базирующихся на концепции объектов. Данная область активно эволюционирует с середины 80-х годов, основываясь на понятиях объекта (сущности), метода (действия) и атрибута (характеристики). Здесь главную роль играют полиморфизм и инкапсуляция, в то время, как в компонентно-ориентированном подходе большее значение придается мета-информации, например, с применением технологии отражения (reflection). Хотя корни объектно-ориентированного проектирования лежат в абстракции данных (к которым добавлены поведенческие характеристики), так называемый responsibility-driven design или проектирование на основе <функциональной> ответственности по SWEBOK* может рассматриваться как альтернатива объектно-ориентированному проектированию.

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

Проектирование на основе структур данных (Data-Structure-Centered Design)

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

Компонентное проектирование (Component-Based Design)

Программные компоненты являются независимыми единицами, которые обладают однозначно-определенными (well-defined) интерфейсами и зависимостями (связями) и могут собираться и развертываться независимо друг от друга. Данный подход призван решить задачи использования, разработки и интеграции таких компонент с целью повышения повторного использования активов (как архитектурных, так и в форме кода).

Компонентно-ориентированное проектирование является одной из наиболее динамично развивающихся концепций проектирования и может рассматриваться как предвестник и основа сервисно-ориентированного подхода (Service-Oriented Architecture, SOA) в проектировании, не рассматриваемого, к сожалению, в SWEBOK, но все более активно использующегося в индустрии и смещающего акценты с аспектов организации связи интерфейс-реализация к обмену информацией на уровне интерфейс-интерфейс (то есть – межкомпонентному взаимодействию). По мнению автора книги, уже наступил тот момент, когда необходимо вводить отдельную тему, посвященную сервисно-ориентированному подходу в проектировании и сервисно-ориентированным архитектурам, как моделям. В частности, нотация UML 2.0 уже позволяет решать ряд вопросов, связанных с визуальным представлением соответствующих архитектурных решений, где сервисы (службы) могут рассматриваться как публикуемая функциональность одиночных компонентов и групп компонентов, объединенных в более “крупные” блоки, обеспечивающие предоставление соответствующей сервисной функциональности.

Другие методы (Other Methods)

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

Конструирование программного обеспечения

Глава базируется на IEEE Guide to the Software Engineering Body of Knowledge - SWEBOK.

Содержит перевод описания области знаний SWEBOK “Software Construction”, с замечаниями и комментариями.

Конструирование программного обеспечения (Software Construction)

Термин конструирование программного обеспечения (software construction) описывает детальное создание рабочей программной системы посредством комбинации кодирования, верификации (проверки), модульного тестирования (unit testing), интеграционного тестирования и отладки.

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

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

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

В процессе конструирования обычно создается большая часть активов программного проекта - конфигурационных элементов (configuration items). Поэтому в реальных проектах просто невозможно рассматривать деятельность по конструированию в отрыве от области знаний “Конфигурационного управления” (Software Configuration Management).

Так как конструирование невозможно без использования соответствующего инструментария и, вероятно, данная деятельность является наиболее инструментально-насыщенной, важную роль в конструировании играет область знаний “Инструменты и методы программной инженерии” (Software Engineering Tools and Methods).

Безусловно, вопросы обеспечения качества значимы для всех областей знаний и этапов жизненного цикла. В то же время, код является основным результирующим элементом программного проекта. Таким образом, явно напрашивается и присутствует связь обсуждаемых вопросов с областью знаний “Качество программного обеспечения” (Software Quality).

Из связанных дисциплин программной инженерии (Related Disciplines of Software Engineering) наиболее тесная и естественная связь данной области знаний существует с компьютерными науками (computer scince). Именно в них, обычно, рассматриваются вопросы построения и использования алгоритмов и практик кодирования. Наконец, конструирование касается и управления проектами (project management), причем, в той степени, насколько деятельность по управлению конструированием важна для достижения результатов конструирования.

Рисунок 4. Область знаний “Конструирование программного обеспечения” [SWEBOK, 2004, с.4-2, рис. 1]
Рисунок 4. Область знаний “Конструирование программного обеспечения” [SWEBOK, 2004, с.4-2, рис. 1]

Основы конструирования (Software Construction Fundamentals)

Фундаментальные основы конструирования программного обеспечения включают:

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

Минимизация сложности (Minimizing Complexity)

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

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

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

Ожидание изменений (Anticipating Changes)

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

Ожидание изменений поддерживается рядом техник, представленных в теме 3.3 “Кодирование”.

Конструирование с возможностью проверки (Constructing for Verification)

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

Среди техник, направленных на достижение такого результата конструирования:

Стандарты в конструировании (Standards in Constructing)

Стандарты, которые напрямую применяются при конструировании, включают:

Использование внешних стандартов. Конструирование зависит от внешних стандартов, связанных с языками программирования, используемым инструментальным обеспечением, техническими интерфейсами и взаимным влиянием Конструирования программного обеспечения и других областей знаний программной инженерии (в том числе, связанных дисциплин, например, управления проектами). Стандарты создаются разными источниками, например, консорциумом OMG – Object Management Group (в частности. Стандарты CORBA, UML, MDA, …), международными организациями по стандартизации такими, как ISO/IEC, IEEE, TMF, …, производителями платформ, операционных сред и т.д. (например, Microsoft, Sun Microsystems, CISCO, NOKIA, …), производителями инструментов, систем управления базами данных ит.п. (Borland, IBM, Microsoft, Sun, Oracle, …). Понимание этого факта позволяет определить достаточный и полный набор стандартов, применяемых в проектной команде или организации в целом.

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

Управление конструированием (Managing Construction)

Модели конструирования (Construction Models)

Модели конструирования определяют комплекс операций, включающих последовательность, результаты (например, исходный код и соответствующие unit-тесты) и другие аспекты, связанные с общим жизненным циклом разработки. В большинстве случаев, модели конструирования определяются используемым стандартом жизненного цикла, применяемыми методологиями и практиками. Некоторые стандарты жизненного цикла, по своей природе, являются ориентированными на конструирование – например, экстремальное программирование (XP- eXtreme Programming). Некоторые рассматривают конструирование в неразрывной связи с проектированием (в части моделирования), например, RUP (Rational Unified Process).

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

Некоторые модели являются более линейными с точки зрения конструирования ПО. К ним относятся, например, водопадная (waterfall) и поэтапная (staged-delivery) модели жизненного цикла (моделям жизненного цикла посвящена специальная глава, написанная Сергеем Орликом и доступная как часть представленных здесь “Основ программной инженерии”). Эти модели рассматривают конструирование как деятельность, которая начинает проводиться только после завершения определенных обязательных к выполнению (prerequisite) работ, включающих детальное определение требований, подробный дизайн и детальное планирование. Более линейные подходы стараются подчеркнуть действия, предваряющие конструирование (т.е. требования и дизайн) и создать более четкое разделение между такими различными типами деятельности. В таких моделях основным содержанием конструирования может быть кодирование.

Другие модели более итеративны, к ним относятся – эволюционное прототипирование, экстремальное программирование и Scrum. Эти подходы сходятся к рассмотрению конструирования как деятельности, которая ведется одновременно с другими видами работ по созданию программного обеспечения и пересекаясь с ними (видимо, здесь имеется в виду взаимозависимость и влияние друг на друга), включая определение требований, проектирование и планирование. Эти подходы смешивают проектирование, кодирование и тестирование, часто рассматривая их комбинацию как конструирование.

Соответственно, что именно подразумевается под “конструированием” зависит в определенной степени от используемой модели жизненного цикла.

Планирование конструирования (Construction Planning)

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

Используемый подход к конструированию влияет на возможность уменьшения (в идеале - минимизации) сложности, готовности к изменениям и конструировании с возможностью проверки.

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

*Заметьте – не распределяют, а распределяются, подразумевая процесс, приводящий к обеспечению явной связи между задачей и ресурсами. В нечетко регламентированных (это ни в коем случае не ругательство, это определение – ведь существует же понятие нечёткая логика, неструктурированные базы данных, например, в отношении нереляционных систем и т.п.) и неформальных методах, таких, как XP, члены проектной группы сами принимают на себя ответственность по решению определенных задач, а “владение” кодом является совместным на основе сотрудничества, как одного из ключевых принципов работы проектной команды.

Измерения в конструировании (Construction Measurement)

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

Код является одним из наиболее четко детерминированных активов проекта (постепенно такими становятся и модели, строящиеся на основе структур метаданных, и тесно связанные с кодом - например, UML). Код является и самим носителям требуемой функциональности. Соответственно, применение измерений в отношении кода становится тем инструментом, который влияет и на управление и на сам код.

Последнее время, большое внимание многие профессиональные разработчики, то есть инженеры-конструкторы программного обеспечения, уделяют рефакторинг кода, как методы его реструктурирования, призванные без изменения содержания (то есть функциональности и функциональной целостности) обеспечить решение задач минимизации сложности, готовности к изменениям (гибкости), прозрачности документирования и многих других актуальных аспектов конструирования. Но, к сожалению, многие забывают о необходимости мотивированности изменений, даже на уровне рефакторинга. Применение измерений, в частности, метрик, позволяет определить необходимость внесения таких изменений, проведения рефакторинга. И не потому что “так, наверное, будет всё же лучше, красивше…”, а потому, что в иерархии наследования из 10 поколений классов – 9 являются абстрактными (“из любви к искусству”), а на 10-м (в силу превышений сроков проекта, после того, как долго и “в кайф” создавали архитектурно-красивый код) “повешено” 20 (!) бизнес-методов. Вот это – действительно обоснованная причина для рефакторинга, который, даже с применением самых совершенных инструментальных средств, вместе с обдумыванием необходимости рефакторинга, а потом, иногда, и борьбой с его последствиями из-за несогласованности членов команды (а это уже жизнь, даже в самом идеальном коллективе, где люди понимают друг друга с полуслова) часто является просто тратой времени. Если применяется рефакторинг, но не применяются метрики – в подавляющем большинстве случаев, это отрицательно влияет на проект. И таких примеров работ, требующих применения измерений, но, к несчастью, игнорирующих их, можно приводить достаточно долго. Вы, наверняка, сами можете рассказать на эту тему много примеров из жизни.

Почему “авторизованный перевод” этой темы SWEBOK оказался столь эмоционален? Практика автора показывает, что в погоне за “красотой”, разработчики слишком часто забывают о цели их работы и воспринимают деятельность по управлению проектами (не буду спорить, иногда лишь формальную, для “прикрытия” всего, что только можно …) со стороны менеджеров и, тем более, любой аудит – как однозначную помеху “полёту мысли”. Зря. Если все именно так обстоит в вашем случае – проект, с большой вероятностью, а иногда и просто, “если не случится чудо”, можно считать пусть и не провальным (“фуух… не закрыли….”), то, наверняка, выйдущим за рамки тех или иных ограничений, будь то сроки, деньги, качество или, наконец, время, которое разработчик мог провести с семьей. И не сидеть ночью, дописывая функциональность или отлавливая очередную ошибку за несколько дней до передачи проекта в эксплуатацию. Все эти вопросы преследуют одну единственную цель – предсказуемость работ и результата. И измерения – важный инструмент достижения этой цели.

Область знаний “Software Engineering Process” уделяет специальное внимание вопросам измерений при создании программного обеспечения.

Практические соображения (Practical Considerations)

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

Проектирование в конструировании (Construction Design)

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

Детали деятельности по проектированию на стадии конструирования в основном те же самые, что и описанные в области знаний “Проектирование программного обеспечения” (Software Design). Отличие заключается в большем внимании деталям.

Языки конструирования (Construction Languages)

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

Простейший тип языков конструирования – конфигурационный язык (configuration language), позволяющий задавать параметры выполнения программной системы.

Инструментальный язык (toolkit language) – язык конструирования из повторно-используемых элементов; обычно строится как сценарный язык (script), выполняемый в соответствующей среде.

Язык программирования (programming language) – наиболее гибкий тип языков конструирования. Содержит минимальный объем информации о конкретных областях приложения и процессе разработки, требуя больше всего (по сравнению с другими типами языков конструирования) усилий на изучение и наработку опыта для эффективного применения при решении конкретных задач.

Существует три основных вида нотаций используемых при определении языков программирования:

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

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

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

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

Сегодняшние работы (и их состояние) в области архитектур и приложений, управляемых моделями, в первую очередь - OMG MDA (Model-Driven Architecture www.omg.org/mda)/UML (Unified Modeling Language www.omg.org/uml), Microsoft DSL (Domain-Specific Language), направлены на то, чтобы использовать ту или иную визуальную нотацию, базирующуюся на мета-моделях, в качестве инструмента, применяемого и для определения функциональной логики системы. Можно ли в чистом виде считать эти нотации именно визуальными - вопрос спорный. Но в терминах, предлагаемых SWEBOK, они относятся именно к визуальным нотациям, так как предполагают однозначную интерпретацию визуального представления в виде текста и наоборот. Кроме того, исторически эти нотации определялись изначально как нотации визуального представления функциональности и уже в дальнейшем эти визуальные представления были отражены на цровне соответствующих мета-моделей (хотя это в большей степени верно для UML, чем DSL, но DSL можно рассматривать и как аналог UML, предполагающий бОльшую свободу применений и интегрированность с конкретной платформой - Microsoft). Другая область стандартов, направленных на применение визуальных нотаций для описания функциональности – Business Process Management Notation (BPMN - www.omg.org/bpmn) и связанный с ней язык Business Process Execution Language, построенный на базе XML. Таким образом, область обоснованного применения визуальных нотаций для конструирования программных систем качественно расшириться и, не исключено, мы станем свидетелями de-facto формирования новой категории нотаций, соглашений и смешанных типов языковых средств, предназначенных для конструирования программного обеспечения как естественного продолжения проектирования.

Кодирование (Coding)

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

Тестирование в конструировании (Construction Testing)

При конструировании используются две формы тестирования, проводимого инженерами, непосредственно создающими исходный код:

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

Тестировании в конструировании обычно включает подмножество видов тестирования, описанных в области знаний “Тестирование программного обеспечения” (Software Testing). Например, тестирование в конструировании обычно не включает системного тестирования, нагрузочного тестирования, usability-тестирования (оценки прозрачности использования) и других видов тестовой деятельности.

IEEE опубликовал два стандарта, посвященных данной теме:

Напрямую с данной темой связаны под-темы SWEBOK 2.1.1 “Unit Testing” и 2.1.2 “Integration Testing”.

Повторное использование (Reuse)

Во введении в стандарт IEEE Std. 1517-99 “IEEE Standard for Information Technology – Software Lifecycle Process – Reuse Processes” даётся следующее понимание повторному использованию в программном обеспечении: “Реализация повторного использования программного обеспечения подразумевает и влечёт за собой нечто большее, чем просто создание и использование библиотек активов. Оно требует формализации практики повторного использования на основе интеграции процессов и деятельности по повторному использованию в сам жизненный цикл программного обеспечения.” В то же время, повторное использование достаточно важно и непосредственно при конструировании программных систем, что подчеркивается включением этой темы в обсуждаемую область знаний конструирования ПО.

Задачи, связанные с повторным использованием в процессе конструирования и тестирования, включают:

Качество конструирования (Construction Quality)

Существует ряд техник, предназначенных для обеспечения качества кода, выполняемых по мере его конструирования. Основные техники обеспечения качества, используемые в процессе конструирования, включают:

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

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

Интеграция (Integration)

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

Кроме упомянутых аспектов интеграции, к обсуждаемым интеграционным вопросам конструирования относятся:

Тестирование программного обеспечения

Глава базируется на IEEE Guide to the Software Engineering Body of Knowledge - SWEBOK.

Содержит перевод описания области знаний SWEBOK “Software Testing”, с замечаниями и комментариями.

Тестирование (software testing) – деятельность, выполняемая для оценки и улучшения качества программного обеспечения. Эта деятельность, в общем случае, базируется на обнаружении дефектов и проблем в программных системах.

Тестирование программных систем состоит из динамической верификации поведения программ на конечном (ограниченном) наборе тестов (set of test cases), выбранных соответствующим образом из обычно выполняемых действий прикладной области и обеспечивающих проверку соответствия ожидаемому поведению системы.

В данном определении тестирования выделены слова, определяющие основные вопросы, которым адресуется данная область знаний:

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

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

В области знаний “Качество программного обеспечения” (Software Quality) техники управления качеством четко разделены на статические (без выполнения кода) и динамические (с выполнением кода). Обе эти категории важны. Данная область знаний - “Тестирование” – касается динамических техник.

Как уже отмечалось ранее, тестирование тесно связано с областью знаний “Конструирование” (Software Construction). Более того, модульное (unit-) и интеграционное тестирование все чаще рассматривают как неотъемлемый элемент деятельности по конструированию.

Рисунок 5. Область знаний “Тестирование программного обеспечения” [SWEBOK, 2004, с.5-2, рис. 1]
Рисунок 5. Область знаний “Тестирование программного обеспечения” [SWEBOK, 2004, с.5-2, рис. 1]

Основы тестирования (Software Testing Fundamentals)

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

Определение тестирования и связанной терминологии достаточно полно даётся в “Глоссарии терминов по программной инженерии” – IEEE Standard 610-90 (Standard Glossary of Software Engineering Terminology).

Недостатки и сбои (Faults vs. Failures)

В литературе, посвященной программной инженерии, встречается множество терминов, описывающих нарушение функционирования программных систем – недостатки (faults), дефекты (defects), сбои (failures), ошибки (errors) и др. Соответствующая терминология, как было указано выше в 1.1.1, описана в IEEE Std. 610-90 также обсуждается в области знаний SWEBOK “Качество программного обеспечения” (Software Quality). Важно чётко разделять причину нарушения работы прикладных систем, обычно описываемую терминами недостаток или дефект, и наблюдаемый нежелательный эффект, вызываемый этими причинами – сбой. Термин ошибка, в зависимости от контекста, может описывать и как причину сбоя, и сам сбой. Тестирование позволяет обнаружить дефекты, приводящие к сбоям.

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

Ключевые вопросы (Key Issues)

Критерии отбора тестов/критерии адекватности тестов, правила прекращения тестирования (Test selection criteria/test adequacy criteria, or stopping rules)

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

Эффективность тестирования/Цели тестирования (Test effectiveness/Objectives for testing)

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

Тестирование для идентификации дефектов (Testing for defect identification)

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

Проблема оракула (The oracle problem)

“Оракул”, в данном контексте, любой агент (человек или программа), оценивающий поведение программы, формулируя вердикт - тест пройден (“pass”) или нет (“fail”).

Теоретические и практические ограничения тестирования (Theoretical and practical limitation of testing)

Теория тестирования выступает против необоснованного уровня доверия к серии успешно пройденных тестов. К сожалению, большинство установленных результатов теории тестирования – негативны, означая, по словам Дейкстры (Dijkstra), то, что “тестирование программы может использоваться для демонстрации наличия дефектов, но никогда не покажет их отсутствие”. Основная причина этого в том, что полное (всеобъемлющее) тестирование недостижимо для реального программного обеспечения.

Проблема неосуществимых путей (The problem of infeasible paths)

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

Тестируемость (Testability)

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

Связь тестирования с другой деятельностью (Relationships of testing with other activities)

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

Уровни тестирования (Test Levels)

Над чем производятся тесты (The target of the test)

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

Модульное тестирование (Unit testing)

Этот уровень тестирования позволяет проверить функционирование отдельно взятого элемента системы. Что считать элементом – модулем системы определяется контекстом. Наиболее полно данный вид тестов описан в стандарте IEEE 1008-87 “Standard for Software Unit Testing”, задающем интегрированную концепцию систематического и документированного подхода к модульному тестированию.

Интеграционное тестирование (Integration testing)

Данный уровень тестирования является процессом проверки взаимодействия между программными компонентами/модулями.

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

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

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

Системное тестирование (System testing)

Системное тестирование охватывает целиком всю систему. Большинство функциональных сбоев должно быть идентифицировано еще на уровне модульных и интеграционных тестов. В свою очередь, системное тестирование, обычно фокусируется на нефункциональных требованиях – безопасности, производительности, точности, надежности т.п.

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

Цели тестирования (Objectivies of Testing)

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

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

Можно выделить следующие, наиболее распространенные и обоснованные цели (а, соответственно, виды) тестирования:

Приёмочное тестирование (Acceptance/qualification testing)

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