Объектно-ориентированное программирование и программная инженерия

Цель - инженерия программ

Разбить на страницы
Показывать лекцию целиком

Введение в инженерию программ

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

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

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

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

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

    Базисные определения

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

    Определение: инженерия программ

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

    Два важных свойства инженерии программ устанавливаются в этом определении — ПО должно быть программным продуктом и иметь определенное качество.

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

    Программный продукт должен удовлетворять комбинации ограничений. Они могут включать:

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

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

    Определение: сопровождение ПО

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

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

    Жаргонный термин будет полезен для обсуждения.

    Сопричастник Термин, используемый в оригинале - stakeholder. Мне не известен его хороший перевод. Пришлось использовать новое слово, которое, как мне кажется, точно передает смысл понятия

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

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

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

    DIAMO - облик инженерии программ

    Для понимания вызовов, стоящих перед инженерией программ, можно рассматривать эту дисциплину как состоящую из пяти частей — пяти граней равной важности. Программирование — это первый компонент одной из частей (второй — реализация). В качестве мнемоники этой классификации будем использовать акроним DIAMO (по первым буквам английских слов, именующих части дисциплины — Describe, Implement, Assess, Manage, Operate. Акроним является префиксом слова Diamond — бриллиант).

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

    (рис 9.1) DIAMO. Бриллиант инженерии программ

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

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

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

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

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

    Составляющие качества

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

    Процесс и продукт

    Обсуждение инженерии программ предполагает два дополняющих друг друга аспекта.

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

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

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

  • Качество процесса, характеризуемое эффективностью процесса разработки.
  • Непосредственное качество продукта, характеризуемое адекватностью продукта в том виде, как он поставляется в последней своей версии.
  • Долговременное качество продукта, характеризуемое будущими перспективами. В мире инженерии программ, где проекты могут проживать длинную жизнь, эти факторы столь же важны, как и непосредственная картина.
  • В каждой области рассмотрим главные цели, начав с наиболее очевидного свойства — качества непосредственного продукта. Обсуждение включает некоторые комментарии, объясняющие, почему некоторые другие факторы играют не столь важную роль. Два общих замечания об этом обзоре:

  • Не будут даваться никакие явные определения поясняемых факторов качества ("простота использования", "легкость изучения"). Соответствующие термины не появятся в разделе "Новый словарь" в конце этой лекции.
  • Можно заметить некоторую относительность в определениях: адекватность означает удовлетворение определенным потребностям, эффективность — это адекватное использование ресурсов. Это не приводит к неопределенности, скорее наоборот, определение целей качества ПО полезно лишь в той мере, насколько они позволяют оценивать продукты или процессы по отношению к достижению поставленных целей. Определения, следовательно, предполагают, что такие цели явно заданы.
  • Эта проблема не просто академическая: вообразите, что вы руководитель проекта и отслеживаете число оставшихся погрешностей в проекте. Когда вы дадите санкцию на выпуск очередного релиза системы: при числе ошибок, равном 1000, 500, 200, 0? В реальной ситуации необходимо классифицировать погрешности: приводящие к зависаниям системы; серьезные, но не критические; небольшие проблемы, такие как несовершенство пользовательского интерфейса; пропущенная функциональность из разряда "хорошо бы иметь", которая может быть отложена на следующий выпуск. На поставленный вопрос невозможно ответить, если не иметь четких критериев, установленных заблаговременно. Мы вернулись назад к оригинальному определению инженерии программ и его требованию "отвечать определенным стандартам качества".
  • На следующем рисунке показана общая классификация факторов качества, которые предстоит рассмотреть.

    Качество непосредственного продукта

    Качество продукта включает следующие факторы.

    (рис 9.2) Факторы качества ПО
  • Адекватность: удовлетворение определенным потребностям пользователя. Другими словами, продукт должен служить целям сообщества пользователей. Другие факторы, часто упоминаемые в этой области, — это полнота и полезность, но оба они менее точные и могут рассматриваться как частные случаи адекватности. Никогда система не обладает полной функциональностью, поскольку всегда найдется такой пользователь, чьи потребности не удовлетворяются системой. Полезность также является субъективным критерием, если только не установлены четкие критерии "полезности".
  • Корректность: выполнение функций системы в соответствии с предписанными спецификациями в случаях, покрываемых спецификациями. Ясно, что это фундаментальное требование. Точно так же ясно, что корректность трудно достижима. Непросто написать программу, работающую в точном соответствии со спецификациями, но и написание самих спецификаций трудная задача, — необходимо учитывать все возможные случаи. Непросто и написать однозначно понимаемый документ со спецификациями.
  • Важным следствием этого определения является вывод, что корректность - понятие относительное. Никогда нельзя сказать, что программная система корректна или некорректна. О корректности системы можно говорить только по отношению к заданной спецификации. В математических терминах "корректность" применяется не к программе, а к паре [программа, спецификация].
  • Устойчивость: насколько хорошо система реагирует на ошибочные ситуации ее использования, выходящие за пределы спецификации. Пользователь мог нажать не ту кнопку, сенсор мог неправильно сработать, другая программа прислала ошибочный ввод, — все такие ситуации не должны быть причиной отказа системы от работы или выдачи неверных результатов. Устойчивость предполагает обработку ошибок и механизмы восстановления системы.
  • Безопасность: насколько хорошо система защищает себя, свои данные, своих пользователей и любые связанные с ней устройства от враждебных попыток нарушить ее работу. К несчастью, говоря об устойчивости, необходимо заботиться не просто об ошибках, — компьютерные системы часто являются целями преднамеренных вражеских атак. Поэтому нельзя писать ПО, особенно работающее в сети, не учитывающее потенциальных угроз.
  • Эффективность (часто называемая производительностью): адекватное использование времени, памяти и других ресурсов, таких как пропускная способность для систем, осуществляющих передачу данных по сети. Мы говорим об адекватности, но не об оптимальности. Если компилируемой системе требуется 1 МВ памяти, но можно уменьшить объем до 0.6 МВ, то такая оптимизация вовсе не обязательно будет полезной, особенно если требует дополнительных затрат. Если вы ожидаете, что ваши пользователи будут иметь достаточно памяти, то лучше потратить время на другие факторы качества. Но если речь идет об устройствах с малой памятью, то оптимизация требуемого пространства может стать критической. И снова речь идет о необходимости объективных критериев.
  • Простота использования: непростой выбор — сделать систему простой в использовании для различных групп пользователей. Часто систему пытаются сделать простой для новичков, но не менее важно помогать экспертам, которые точно знают, что им необходимо, и не хотят проходить через подсказки и информационные окна. Так что "простоту" необходимо поддерживать в широком диапазоне от новичков до экспертов. Каждый из нас новичок в использовании одних инструментов и эксперт — в других. Каждый из нас проходил путь от новичка к эксперту, и система должна поддерживать нас на этом пути.
  • Легкость (простота) обучения: понятие, тесно связанное с предыдущим фактором.
  • Долговременное качество продукта

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

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

    Качества, ориентированные на долгий период, включают:

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

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

  • переносимость: насколько просто перенести ПО на другие платформы. Под платформой здесь понимается комбинация архитектуры компьютера и его операционной системы плюс другие ресурсы, необходимые системе, такие как системы управления базами данных. За последние десятилетия в ИТ-индустрии накоплен большой опыт по конструированию переносимого ПО. Для общецелевых вычислений на рынке компьютерного железа предлагается несколько архитектур (Pentium и совместимые с ним, Sparc, PowerPC), мир операционных систем — это Windows, Unix-варианты, такие как Linux, Solaris и Mac OS. Что же касается языков программирования, то большинство из них доступны на разных платформах;
  • повторное использование: какая доля продукта может быть использована в будущих разработках. Многим приложениям нужна одна и та же функциональность, либо общей природы (структуры данных и фундаментальные алгоритмы, механизмы GUI), либо нацеленная на одну и ту же прикладную область. Повторно используемое ПО — это ПО, достаточно независимое от конкретного проекта и допускающее использование в последующих проектах. Объектная технология направлена на повторное использование и ведет к построению программных компонентов, служащих потребностям многих разработок (подумайте о библиотеке Traffic и обо всех библиотеках, на которых она сама основана). Даже не создавая целенаправленно программных компонентов, следует прилагать усилия по созданию ПО, допускающего использование в будущих проектах.
  • В литературе можно найти ссылки на фактор качества, называемый сопровождаемостью, предполагающий простоту работы с системой после выпуска начального релиза. Это важное понятие не является независимым фактором, а представляет комбинацию уже рассмотренных долговременных факторов, так как сопровождаемость включает и фиксацию ошибок, и расширение функциональности и перенос на другие платформы.

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

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

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

    Качество процесса

    Факторы процесса оценивают качество механизмов, применяемых для создания ПО. Они включают:

  • скорость разработки: способность поставлять продукт в сжатые сроки. Каждый проект должен заботиться об этом, клиенты ждут, конкуренты не дремлют, акционеры размышляют;
  • эффективность стоимости. Об этом также заботятся почти все проекты. В инженерии программ (в отличие от некоторых других видов инженерии) стоимость готового продукта незначительна. Над всем доминирует стоимость разработки (за исключением, возможно, расходов на маркетинг, которые могут быть существенными, особенно для продуктов, ориентированных на массовый рынок). Стоимость разработки определяют затраты на персонал, оборудование, офис. По этой причине стандартной мерой стоимости является человеко-месяц: средняя стоимость расходов на одного работника в месяц (все включено);
  • эффективность сотрудничества: эффективность процедур, обеспечивающих наилучшее взаимодействие всех членов команды, работающей над проектом. Серьезные проекты могут включать большое число участников. Требуется уделять особое внимание механизмам координации. Коммуникация участников — довольно деликатная проблема, которая для команд большого размера может перевесить все остальные аспекты разработки. Экстремальная форма этого феномена известна как закон Брукса (по имени проектировщика операционной системы IBM OS/360), который говорит, что "добавление людей в проект, не укладывающийся в сроки, удлиняет время разработки". Хотя можно считать, что этот закон верен только для плохо управляемых проектов, но он ясно характеризует суть проблемы коммуникации;
  • вовлеченность сопричастников: степень учета в проекте всех релевантных потребностей и точек зрения людей, так или иначе вовлеченных в проект;
  • встроенное оценивание: включение в процесс механизмов и процедур, измеряющих факторы качества на хорошо определенных этапах. Качество не должно только декларироваться, но его нужно проверять и принуждать к его соблюдению. Хорошо организованный процесс интегрирует эту задачу как один из своих компонентов;
  • предсказуемость: включение в процесс надежных методов оценивания других факторов качества — в частности, скорости и стоимости разработки. Предсказуемость — одна из наиболее важных характеристик хорошего процесса. Иногда гарантированная дата так же важна, как и ранняя дата. В ИТ-индустрии нет достаточной статистики в этой области, мы не знаем, сколь много проектов не выдерживали сроков и выходили за рамки отведённого бюджета. Ситуация с годами улучшается благодаря применению принципов и методов инженерии программ;
  • измеримость: пригодность количественных критериев для определения достижимости других факторов качества, как процесса, так и продукта, например, методы измерения уровня ошибок. Эффективное управление нуждается в точных измерениях развития проекта. Этот критерий тесно связан с двумя предшествующими, так как, чтобы делать предсказания и давать оценки, требуется возможность проведения измерений;
  • воспроизводимость: независимость разработки, методов управления и предсказания от несущественных атрибутов конкретных проектов. В большинстве случаев индустриальная разработка проекта не ведется изолировано. Крайне важно достигнутые успешные результаты в одном проекте воспроизводить в других проектах (ошибки в проектах также заслуживают тщательного анализа);
  • самосовершенствование: включение в саму спецификацию процесса механизмов, квалифицирующих и улучшающих этот процесс. Организации, подобно людям, могут обучаться на собственном опыте. Критерий самосовершенствования оценивает, в какой степени процесс, определённый в организации, отвечает этому феномену, за счет включения встроенных механизмов оценки, которые могут служить обратной связью для процесса, адаптируя его в соответствии с уроками обучения.
  • Модели процессов, такие как CMMI (изучаемые позже в этой лекции), ставят эти факторы во главу угла, в частности, последние пять, обучая культуре производства, где оценивание, предсказуемость, измеримость, воспроизводимость и самосовершенствование являются встроенными центральными практиками.

    Компромиссы

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

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

    Главные виды деятельности в процессе разработки ПО

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

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

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

  • Функциональные требования, описывающие результаты или действия системы: "Если телефон пользователя переходит из одной области покрытия в другую, то соединение автоматически должно переключаться на точку доступа в новой области".
  • Нефункциональные требования, специфицирующие ограничения на операции системы. Они включают требования к производительности, например, временные ("Для точки доступа, отстоящей менее чем на два километра, время переключения должно занимать не более одной секунды"). Здесь же задаются ограничения на память, безопасность ("все сообщения, передаваемые через точку доступа, должны быть зашифрованы"), пропускную способность. Они также покрывают воздействие на системное окружение и людей, таких как служащие: влияние на практику их работы.
  • Спецификация является точным описанием отдельных элементов системы. Требования ориентированы на клиента. Спецификация преобразует их в форму, непосредственно используемую при разработке системы. Главная разница состоит в законченности и точности: спецификация должна давать недвусмысленный ответ на каждый релевантный вопрос об операциях системы.

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

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

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

    Создание документации представляет задачу описания различных аспектов системы, чтобы помочь ее пользователям и другим сопричастникам, в частности, разработчикам. Помимо документов, создаваемых для пользователей, она может включать планы проекта (для менеджеров), документы требований, спецификации, планы проектирования. Слово "документ" заменило более традиционное слово "отчет", представляемый обычно как бумажный документ. Сегодняшняя документация представляется в электронном виде, как Web-страницы, онлайновая справка, регулярно обновляемая. Документация является частью программного текста в виде заголовочных комментариев — специальных документируемых комментариев, которые есть в таких языках, как Eiffel, Java и C#.

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

  • Верификация является внутренней оценкой согласованности продукта, рассматриваемого сам по себе. Типичный пример: на уровне реализации проверка типов позволяет предотвратить использование переменной, объявленной REAL , как если бы она имела тип INTEGER .
  • Проверка правильности дает оценку продукта по отношению свойств, которые должны выполняться: код сравнивается с проектом, проект — со спецификациями, спецификации — с требованиями, документация — со стандартами, применяемые практики — с правилами компании, даты поставки — с намеченными сроками, обнаруженные уровни дефектов — с заявленными целями, набор тестов — со сферой действия метрик. Популярная версия, характеризующая разницу между верификацией и проверкой правильности, утверждает, что верификация проверяет, "делаются ли вещи правильно", в то время как проверка правильности проверяет, "делаются ли правильные вещи".
  • Сопровождение, как уже отмечалось, не представляет вид независимой деятельности, а является комбинацией перечисленных выше задач. Единственной отличительной чертой сопровождения является то, что сопровождение начинается с той минуты, когда выпущен первый релиз системы.

    Модели жизненного цикла и разработка в стиле AGILE

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

    Модель водопада

    (рис 9.3) Модель водопада

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

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

    Этот и некоторые другие элементы этого раздела являются адаптированными материалами главы 28 из моей книги "Объектно-ориентированное конструирование программных систем", 2006 г., которая содержит более детальное обсуждение моделей процесса.

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

    Спиральная модель

    (рис 9.4) Спиральная модель

    В своей книге (Software Engineering Economics Prentice Hall, 1988) Барри Боем предложил модель, которая смягчает жесткость, применяя итеративный подход, основанный на успешных прототипах. Эта модель известна под именем спиральной модели и показана на следующем рисунке.

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

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

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

    Кластерная модель

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

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

    (рис 9.5) Кластерная модель

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

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

    Agile - гибкая методология разработки

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

  • работающий код как принципиальная мера прогресса разработки;
  • сотрудничество между разработчиками и заказчиками, которые имеют своих представителей в команде разработчиков;
  • частые коммуникации;
  • тесты (а не спецификации) руководят разработкой;
  • небольшие добавления в проект обеспечивают постоянную обратную связь и непрерывную интеграцию: непосредственная компиляция и тестирование изменений; незамедлительная их интеграция в основной проект, не ожидая недель и месяцев, уменьшая риск того, что две части проекта разойдутся и их слияние будет затруднительным;
  • специфические практики, такие как "парное программирование" (разработчики разбиваются на пары и создают код вместе, что позволяет раньше обнаруживать ошибки).
  • Появление в девяностые годы этой гибкой методологии вызвало ожесточенные споры. Это воспринималось как социологический феномен — революция программистов против засилья менеджеров. Теперь все понемногу успокоилось, и многие практики, такие как непрерывная интеграция, широко приняты. Другие, такие как "тесты предпочтительнее спецификаций", остаются под вопросом. Но становится ясно, что процесс разработки ПО может быть как структурированным, так и гибким (agile).

    Страницы:

    Введение в инженерию программ

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

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

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

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

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

    Базисные определения

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

    Определение: инженерия программ

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

    Два важных свойства инженерии программ устанавливаются в этом определении — ПО должно быть программным продуктом и иметь определенное качество.

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

    Программный продукт должен удовлетворять комбинации ограничений. Они могут включать:

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

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

    Определение: сопровождение ПО

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

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

    Жаргонный термин будет полезен для обсуждения.

    Сопричастник Термин, используемый в оригинале - stakeholder. Мне не известен его хороший перевод. Пришлось использовать новое слово, которое, как мне кажется, точно передает смысл понятия

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

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

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

    DIAMO - облик инженерии программ

    Для понимания вызовов, стоящих перед инженерией программ, можно рассматривать эту дисциплину как состоящую из пяти частей — пяти граней равной важности. Программирование — это первый компонент одной из частей (второй — реализация). В качестве мнемоники этой классификации будем использовать акроним DIAMO (по первым буквам английских слов, именующих части дисциплины — Describe, Implement, Assess, Manage, Operate. Акроним является префиксом слова Diamond — бриллиант).

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

    (рис 9.1) DIAMO. Бриллиант инженерии программ

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

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

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

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

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

    Составляющие качества

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

    Процесс и продукт

    Обсуждение инженерии программ предполагает два дополняющих друг друга аспекта.

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

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

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

  • Качество процесса, характеризуемое эффективностью процесса разработки.
  • Непосредственное качество продукта, характеризуемое адекватностью продукта в том виде, как он поставляется в последней своей версии.
  • Долговременное качество продукта, характеризуемое будущими перспективами. В мире инженерии программ, где проекты могут проживать длинную жизнь, эти факторы столь же важны, как и непосредственная картина.
  • В каждой области рассмотрим главные цели, начав с наиболее очевидного свойства — качества непосредственного продукта. Обсуждение включает некоторые комментарии, объясняющие, почему некоторые другие факторы играют не столь важную роль. Два общих замечания об этом обзоре:

  • Не будут даваться никакие явные определения поясняемых факторов качества ("простота использования", "легкость изучения"). Соответствующие термины не появятся в разделе "Новый словарь" в конце этой лекции.
  • Можно заметить некоторую относительность в определениях: адекватность означает удовлетворение определенным потребностям, эффективность — это адекватное использование ресурсов. Это не приводит к неопределенности, скорее наоборот, определение целей качества ПО полезно лишь в той мере, насколько они позволяют оценивать продукты или процессы по отношению к достижению поставленных целей. Определения, следовательно, предполагают, что такие цели явно заданы.
  • Эта проблема не просто академическая: вообразите, что вы руководитель проекта и отслеживаете число оставшихся погрешностей в проекте. Когда вы дадите санкцию на выпуск очередного релиза системы: при числе ошибок, равном 1000, 500, 200, 0? В реальной ситуации необходимо классифицировать погрешности: приводящие к зависаниям системы; серьезные, но не критические; небольшие проблемы, такие как несовершенство пользовательского интерфейса; пропущенная функциональность из разряда "хорошо бы иметь", которая может быть отложена на следующий выпуск. На поставленный вопрос невозможно ответить, если не иметь четких критериев, установленных заблаговременно. Мы вернулись назад к оригинальному определению инженерии программ и его требованию "отвечать определенным стандартам качества".
  • На следующем рисунке показана общая классификация факторов качества, которые предстоит рассмотреть.

    Качество непосредственного продукта

    Качество продукта включает следующие факторы.

    (рис 9.2) Факторы качества ПО
  • Адекватность: удовлетворение определенным потребностям пользователя. Другими словами, продукт должен служить целям сообщества пользователей. Другие факторы, часто упоминаемые в этой области, — это полнота и полезность, но оба они менее точные и могут рассматриваться как частные случаи адекватности. Никогда система не обладает полной функциональностью, поскольку всегда найдется такой пользователь, чьи потребности не удовлетворяются системой. Полезность также является субъективным критерием, если только не установлены четкие критерии "полезности".
  • Корректность: выполнение функций системы в соответствии с предписанными спецификациями в случаях, покрываемых спецификациями. Ясно, что это фундаментальное требование. Точно так же ясно, что корректность трудно достижима. Непросто написать программу, работающую в точном соответствии со спецификациями, но и написание самих спецификаций трудная задача, — необходимо учитывать все возможные случаи. Непросто и написать однозначно понимаемый документ со спецификациями.
  • Важным следствием этого определения является вывод, что корректность - понятие относительное. Никогда нельзя сказать, что программная система корректна или некорректна. О корректности системы можно говорить только по отношению к заданной спецификации. В математических терминах "корректность" применяется не к программе, а к паре [программа, спецификация].
  • Устойчивость: насколько хорошо система реагирует на ошибочные ситуации ее использования, выходящие за пределы спецификации. Пользователь мог нажать не ту кнопку, сенсор мог неправильно сработать, другая программа прислала ошибочный ввод, — все такие ситуации не должны быть причиной отказа системы от работы или выдачи неверных результатов. Устойчивость предполагает обработку ошибок и механизмы восстановления системы.
  • Безопасность: насколько хорошо система защищает себя, свои данные, своих пользователей и любые связанные с ней устройства от враждебных попыток нарушить ее работу. К несчастью, говоря об устойчивости, необходимо заботиться не просто об ошибках, — компьютерные системы часто являются целями преднамеренных вражеских атак. Поэтому нельзя писать ПО, особенно работающее в сети, не учитывающее потенциальных угроз.
  • Эффективность (часто называемая производительностью): адекватное использование времени, памяти и других ресурсов, таких как пропускная способность для систем, осуществляющих передачу данных по сети. Мы говорим об адекватности, но не об оптимальности. Если компилируемой системе требуется 1 МВ памяти, но можно уменьшить объем до 0.6 МВ, то такая оптимизация вовсе не обязательно будет полезной, особенно если требует дополнительных затрат. Если вы ожидаете, что ваши пользователи будут иметь достаточно памяти, то лучше потратить время на другие факторы качества. Но если речь идет об устройствах с малой памятью, то оптимизация требуемого пространства может стать критической. И снова речь идет о необходимости объективных критериев.
  • Простота использования: непростой выбор — сделать систему простой в использовании для различных групп пользователей. Часто систему пытаются сделать простой для новичков, но не менее важно помогать экспертам, которые точно знают, что им необходимо, и не хотят проходить через подсказки и информационные окна. Так что "простоту" необходимо поддерживать в широком диапазоне от новичков до экспертов. Каждый из нас новичок в использовании одних инструментов и эксперт — в других. Каждый из нас проходил путь от новичка к эксперту, и система должна поддерживать нас на этом пути.
  • Легкость (простота) обучения: понятие, тесно связанное с предыдущим фактором.
  • Долговременное качество продукта

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

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

    Качества, ориентированные на долгий период, включают:

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

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

  • переносимость: насколько просто перенести ПО на другие платформы. Под платформой здесь понимается комбинация архитектуры компьютера и его операционной системы плюс другие ресурсы, необходимые системе, такие как системы управления базами данных. За последние десятилетия в ИТ-индустрии накоплен большой опыт по конструированию переносимого ПО. Для общецелевых вычислений на рынке компьютерного железа предлагается несколько архитектур (Pentium и совместимые с ним, Sparc, PowerPC), мир операционных систем — это Windows, Unix-варианты, такие как Linux, Solaris и Mac OS. Что же касается языков программирования, то большинство из них доступны на разных платформах;
  • повторное использование: какая доля продукта может быть использована в будущих разработках. Многим приложениям нужна одна и та же функциональность, либо общей природы (структуры данных и фундаментальные алгоритмы, механизмы GUI), либо нацеленная на одну и ту же прикладную область. Повторно используемое ПО — это ПО, достаточно независимое от конкретного проекта и допускающее использование в последующих проектах. Объектная технология направлена на повторное использование и ведет к построению программных компонентов, служащих потребностям многих разработок (подумайте о библиотеке Traffic и обо всех библиотеках, на которых она сама основана). Даже не создавая целенаправленно программных компонентов, следует прилагать усилия по созданию ПО, допускающего использование в будущих проектах.
  • В литературе можно найти ссылки на фактор качества, называемый сопровождаемостью, предполагающий простоту работы с системой после выпуска начального релиза. Это важное понятие не является независимым фактором, а представляет комбинацию уже рассмотренных долговременных факторов, так как сопровождаемость включает и фиксацию ошибок, и расширение функциональности и перенос на другие платформы.

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

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

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

    Качество процесса

    Факторы процесса оценивают качество механизмов, применяемых для создания ПО. Они включают:

  • скорость разработки: способность поставлять продукт в сжатые сроки. Каждый проект должен заботиться об этом, клиенты ждут, конкуренты не дремлют, акционеры размышляют;
  • эффективность стоимости. Об этом также заботятся почти все проекты. В инженерии программ (в отличие от некоторых других видов инженерии) стоимость готового продукта незначительна. Над всем доминирует стоимость разработки (за исключением, возможно, расходов на маркетинг, которые могут быть существенными, особенно для продуктов, ориентированных на массовый рынок). Стоимость разработки определяют затраты на персонал, оборудование, офис. По этой причине стандартной мерой стоимости является человеко-месяц: средняя стоимость расходов на одного работника в месяц (все включено);
  • эффективность сотрудничества: эффективность процедур, обеспечивающих наилучшее взаимодействие всех членов команды, работающей над проектом. Серьезные проекты могут включать большое число участников. Требуется уделять особое внимание механизмам координации. Коммуникация участников — довольно деликатная проблема, которая для команд большого размера может перевесить все остальные аспекты разработки. Экстремальная форма этого феномена известна как закон Брукса (по имени проектировщика операционной системы IBM OS/360), который говорит, что "добавление людей в проект, не укладывающийся в сроки, удлиняет время разработки". Хотя можно считать, что этот закон верен только для плохо управляемых проектов, но он ясно характеризует суть проблемы коммуникации;
  • вовлеченность сопричастников: степень учета в проекте всех релевантных потребностей и точек зрения людей, так или иначе вовлеченных в проект;
  • встроенное оценивание: включение в процесс механизмов и процедур, измеряющих факторы качества на хорошо определенных этапах. Качество не должно только декларироваться, но его нужно проверять и принуждать к его соблюдению. Хорошо организованный процесс интегрирует эту задачу как один из своих компонентов;
  • предсказуемость: включение в процесс надежных методов оценивания других факторов качества — в частности, скорости и стоимости разработки. Предсказуемость — одна из наиболее важных характеристик хорошего процесса. Иногда гарантированная дата так же важна, как и ранняя дата. В ИТ-индустрии нет достаточной статистики в этой области, мы не знаем, сколь много проектов не выдерживали сроков и выходили за рамки отведённого бюджета. Ситуация с годами улучшается благодаря применению принципов и методов инженерии программ;
  • измеримость: пригодность количественных критериев для определения достижимости других факторов качества, как процесса, так и продукта, например, методы измерения уровня ошибок. Эффективное управление нуждается в точных измерениях развития проекта. Этот критерий тесно связан с двумя предшествующими, так как, чтобы делать предсказания и давать оценки, требуется возможность проведения измерений;
  • воспроизводимость: независимость разработки, методов управления и предсказания от несущественных атрибутов конкретных проектов. В большинстве случаев индустриальная разработка проекта не ведется изолировано. Крайне важно достигнутые успешные результаты в одном проекте воспроизводить в других проектах (ошибки в проектах также заслуживают тщательного анализа);
  • самосовершенствование: включение в саму спецификацию процесса механизмов, квалифицирующих и улучшающих этот процесс. Организации, подобно людям, могут обучаться на собственном опыте. Критерий самосовершенствования оценивает, в какой степени процесс, определённый в организации, отвечает этому феномену, за счет включения встроенных механизмов оценки, которые могут служить обратной связью для процесса, адаптируя его в соответствии с уроками обучения.
  • Модели процессов, такие как CMMI (изучаемые позже в этой лекции), ставят эти факторы во главу угла, в частности, последние пять, обучая культуре производства, где оценивание, предсказуемость, измеримость, воспроизводимость и самосовершенствование являются встроенными центральными практиками.

    Компромиссы

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

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

    Главные виды деятельности в процессе разработки ПО

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

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

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

  • Функциональные требования, описывающие результаты или действия системы: "Если телефон пользователя переходит из одной области покрытия в другую, то соединение автоматически должно переключаться на точку доступа в новой области".
  • Нефункциональные требования, специфицирующие ограничения на операции системы. Они включают требования к производительности, например, временные ("Для точки доступа, отстоящей менее чем на два километра, время переключения должно занимать не более одной секунды"). Здесь же задаются ограничения на память, безопасность ("все сообщения, передаваемые через точку доступа, должны быть зашифрованы"), пропускную способность. Они также покрывают воздействие на системное окружение и людей, таких как служащие: влияние на практику их работы.
  • Спецификация является точным описанием отдельных элементов системы. Требования ориентированы на клиента. Спецификация преобразует их в форму, непосредственно используемую при разработке системы. Главная разница состоит в законченности и точности: спецификация должна давать недвусмысленный ответ на каждый релевантный вопрос об операциях системы.

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

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

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

    Создание документации представляет задачу описания различных аспектов системы, чтобы помочь ее пользователям и другим сопричастникам, в частности, разработчикам. Помимо документов, создаваемых для пользователей, она может включать планы проекта (для менеджеров), документы требований, спецификации, планы проектирования. Слово "документ" заменило более традиционное слово "отчет", представляемый обычно как бумажный документ. Сегодняшняя документация представляется в электронном виде, как Web-страницы, онлайновая справка, регулярно обновляемая. Документация является частью программного текста в виде заголовочных комментариев — специальных документируемых комментариев, которые есть в таких языках, как Eiffel, Java и C#.

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

  • Верификация является внутренней оценкой согласованности продукта, рассматриваемого сам по себе. Типичный пример: на уровне реализации проверка типов позволяет предотвратить использование переменной, объявленной REAL , как если бы она имела тип INTEGER .
  • Проверка правильности дает оценку продукта по отношению свойств, которые должны выполняться: код сравнивается с проектом, проект — со спецификациями, спецификации — с требованиями, документация — со стандартами, применяемые практики — с правилами компании, даты поставки — с намеченными сроками, обнаруженные уровни дефектов — с заявленными целями, набор тестов — со сферой действия метрик. Популярная версия, характеризующая разницу между верификацией и проверкой правильности, утверждает, что верификация проверяет, "делаются ли вещи правильно", в то время как проверка правильности проверяет, "делаются ли правильные вещи".
  • Сопровождение, как уже отмечалось, не представляет вид независимой деятельности, а является комбинацией перечисленных выше задач. Единственной отличительной чертой сопровождения является то, что сопровождение начинается с той минуты, когда выпущен первый релиз системы.

    Модели жизненного цикла и разработка в стиле AGILE

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

    Модель водопада

    (рис 9.3) Модель водопада

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

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

    Этот и некоторые другие элементы этого раздела являются адаптированными материалами главы 28 из моей книги "Объектно-ориентированное конструирование программных систем", 2006 г., которая содержит более детальное обсуждение моделей процесса.

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

    Спиральная модель

    (рис 9.4) Спиральная модель

    В своей книге (Software Engineering Economics Prentice Hall, 1988) Барри Боем предложил модель, которая смягчает жесткость, применяя итеративный подход, основанный на успешных прототипах. Эта модель известна под именем спиральной модели и показана на следующем рисунке.

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

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

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

    Кластерная модель

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

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

    (рис 9.5) Кластерная модель

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

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

    Agile - гибкая методология разработки

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

  • работающий код как принципиальная мера прогресса разработки;
  • сотрудничество между разработчиками и заказчиками, которые имеют своих представителей в команде разработчиков;
  • частые коммуникации;
  • тесты (а не спецификации) руководят разработкой;
  • небольшие добавления в проект обеспечивают постоянную обратную связь и непрерывную интеграцию: непосредственная компиляция и тестирование изменений; незамедлительная их интеграция в основной проект, не ожидая недель и месяцев, уменьшая риск того, что две части проекта разойдутся и их слияние будет затруднительным;
  • специфические практики, такие как "парное программирование" (разработчики разбиваются на пары и создают код вместе, что позволяет раньше обнаруживать ошибки).
  • Появление в девяностые годы этой гибкой методологии вызвало ожесточенные споры. Это воспринималось как социологический феномен — революция программистов против засилья менеджеров. Теперь все понемногу успокоилось, и многие практики, такие как непрерывная интеграция, широко приняты. Другие, такие как "тесты предпочтительнее спецификаций", остаются под вопросом. Но становится ясно, что процесс разработки ПО может быть как структурированным, так и гибким (agile).

    Вернуться к учебному плану