Программная инженерия
Программная инженерия — это отрасль компьютерных наук, изучающая создание надёжного и качественного программного обеспечения на основе инженерных методов и подходов, а также организацию его эксплуатации и сопровождения. Предмет программной инженерии[1] объединяет компьютерные науки, прикладные науки и основы инженерного дела, на которых строится современная техника[2].
Терминология
Существуют разные авторитетные определения программной инженерии, сформулированные ведущими специалистами:
- Программная инженерия — изучение принципов и методологий разработки и поддержки программных систем (Зелковиц, 1978).
- Программная инженерия — практическое применение научных знаний к проектированию и созданию компьютерных программ и сопутствующей документации, необходимой для их разработки, эксплуатации и обслуживания; также известна как разработка или производство программного обеспечения (Бём, 1976).
- Программная инженерия связана с формализацией инженерных принципов и методов с целью получения программного обеспечения экономически выгодным, надёжным и работоспособным на реальных машинах способом (Бауэр, 1972).
- Программная инженерия — это систематический, дисциплинированный и количественный подход к разработке, эксплуатации и сопровождению программного обеспечения (IEEE Standard Glossary of Software Engineering Terminology[3]).
Термин «инженер-программист» широко используется в бизнес-среде, однако не всегда лица с такой должностью имеют классическое инженерное образование[4].
Ряд специалистов считают, что термин «разработка программного обеспечения» более уместен, чем «программная инженерия», поскольку последний подразумевает уровень формализации и стандартов, не всегда необходимый в любой разработке программного обеспечения.
В русском языке используются оба варианта: «программная инженерия» и «инженерия программного обеспечения».
Создание программного обеспечения — процесс во многом творческий, однако программная инженерия стремится его систематизировать для снижения рисков неудачи, используя проверенные на практике методы.
Программная инженерия — это использование инженерных подходов и инструментов, позволяющих наиболее эффективно достигать требуемого результата. В отличие от «чистого» решения проблем, она подразумевает выбор наиболее подходящего решения из множества возможных.
Использование инженерных стандартов и методик позволяет производить программное обеспечение индустриальным образом, создавая инновационные продукты, способные повысить эффективность и производительность пользователей. Качество технологической инфраструктуры и программных решений прямо влияет на уровень компании и её конкурентоспособность.
История
Первые электронные вычислительные машины появились в 1940-х годах[5]. В этот период разработка программного обеспечения была столь нова, что сложно было предсказывать сроки завершения проектов, многие из которых выходили за рамки бюджета и времени. Часто программы нужно было переписывать для новых машин, которые появлялись раз в год-два, что быстро делало предыдущие решения устаревшими.
Термин «программная инженерия» (англ. Software Engineering) впервые был использован в конце 1950-х годов. Развитие дисциплины было связано с так называемым кризисом программного обеспечения 1960—1980-х годов. Основной задачей программной инженерии стало внедрение принципов и методов, способных упорядочить процессы разработки и сопровождения сложных программных систем.
Кроме системных проблем 1960—1980-х годов, дисциплину затронули аварии, такие как катастрофа с аппаратом для лучевой терапии Therac-25, приведшая к гибели шести человек из-за программных ошибок[6]. Это продемонстрировало высокие риски, связанные с программным обеспечением[7].
С начала 1980-х годов[8] программная инженерия становится отдельной профессией, наряду с компьютерными науками и классическим инженерным делом. Ранняя работа с программами строилась на перфокартах и медленной ручной обработке.
Постоянная необходимость адаптации ПО под новые аппаратные платформы привела к созданию языков высокого уровня. С появлением открытого ПО многие организации стали распространять собственные наработки широкой аудитории.
В течение 1980-х годов стоимость сопровождения и обслуживания программного обеспечения превысила затраты на его непосредственную разработку, и в 1990-е росла на 30% каждый десятилетний период. В 1995 году многие проекты официально функционировали, но не считались успешными: средний проект выходил за рамки по времени на 50%, а 75% крупных программ были настолько проблемными, что не использовались заказчиком или не соответствовали его требованиям.
Одной из причин «кризиса ПО» называлось отсутствие профессиональной дисциплины среди программистов.
Практически каждое новое технологическое решение в 1970–1990-е годы провозглашалось панацеей, однако поиск единственного универсального подхода не привёл к успеху — область слишком сложна, и разные проблемы требуют разных инструментов.
Распространение Интернета значительно увеличило спрос на масштабируемые интернациональные информационные системы. Разработчикам приходилось обрабатывать большие объёмы графических, мультимедийных и языковых данных, создавать системы для многозадачного и многоязычного взаимодействия.
Программная инженерия стала отраслью с капитализацией до 90 миллиардов долларов в год, а такие технологии, как интернет-браузеры и HTML, коренным образом изменили характер передачи и восприятия информации.
Широкое распространение сетей привело к проблемам с вирусами, спамом и необходимостью разрабатывать всё новые системы защиты.
Спрос на дешёвые решения стимулировал развитие более быстрых и простых методологий, пригодных для небольших проектов или быстрого создания функционального ПО.
Цели
Программная инженерия использует методы и стандарты, позволяющие добиваться оптимальных результатов при создании программного обеспечения:
- Улучшение проектирования приложений с учётом специфики задач организации или пользователя.
- Повышение качества при разработке комплексных программных систем.
- Точность оценки затрат и сроков разработки.
- Повышение эффективности путём внедрения стандартов и замера качества.
- Организация командной работы при разработке и сопровождении программ.
- Внедрение эффективных процедур тестирования и улучшений ПО[9].
Ресурсы
Кадровый ресурс — все участники планирования и реализации ПО (менеджеры, опытные программисты и др.). Оптимальная численность определяется после оценки трудоёмкости проекта.
Аппаратная и программная среда проекта: аппаратные ресурсы обеспечивают физическую платформу разработки[10].
Социально-экономические аспекты
В США программное обеспечение обеспечило до 1/8 всего прироста ВВП в 1990-е годы (около 90 миллиардов долларов в год) и 1/9 прироста производительности (до 33 миллиардов долларов в год). По оценкам, программная инженерия внесла $1 трлн в экономический рост за десятилетие.
Сфера обработки естественного языка также активно расширяется.
Программная инженерия изменила культуру современного мира благодаря массовому использованию вычислительной техники. Электронная почта, WWW и мгновенный обмен сообщениями предоставили новые способы взаимодействия. ПО повысило качество и снизило стоимость социальных служб и инфраструктуры. Программная инженерия и связанные с ней методики были применены в таких проектах, как GNU/Linux, программное обеспечение кораблей космической программы США, банковских системах.
Нотации
UML (Unified Modeling Language) — широко используемый язык описания и спецификации методов и документов по проектированию программных систем[11]. UML включает множество видов диаграмм для отображения используемых случаев (use-case), классов, компонентов, развёртывания и др.
BPMN (Business Process Model and Notation) предназначена для визуализации и оптимизации бизнес-процессов на диаграммах, напоминающих диаграммы потоков данных. В BPMN выделяются потоки, соединительные элементы, «пулы» и «дорожки» (для участников процесса), а также артефакты: данные, группы, аннотации[11].
DFD позволяет наглядно отобразить движение и преобразование данных в системе, описывать процессы обработки, хранилища данных и точки взаимодействия. Автор — Ларри Константайн, ключевой элемент — графическое моделирование потоков данных[12].
CASE-средства
CASE (Computer-Aided Software Engineering) — инструменты автоматизации процессов жизненного цикла ПО, многие из которых используют графические модели[13].
Методология
Одной из центральных целей программной инженерии является поиск процессов и методологий разработки, обеспечивающих системность, предсказуемость и повторяемость, а также улучшение производительности и качества ПО.
Жизненный цикл программного обеспечения включает ряд взаимосвязанных фаз:
Выявление целей, задач и ресурсов проекта, анализ контекста бизнеса, определение условий эксплуатации и ограничений.
Важна качественная проработка входных и выходных данных, способов взаимодействия с пользователем, интеграции с внешними устройствами, а также требований к производительности и надёжности.
Правильный анализ требований часто осложнён: клиенты не всегда в полной мере осознают свои нужды, а требования могут быть неполными или даже противоречивыми. В этой фазе используются формализованные подходы и стандарты, такие как CMMI, а также диаграммы сущность-связь и детальное описание всех задействованных бизнес-объектов.
Стандарт IEEE Std. 830-1998 регламентирует спецификацию требований к программному обеспечению (Software Requirements Specification).
Ключевые цели этапа:
- Обеспечить контроль и взаимодействие пользователя с системой.
- Оценить ресурсы и сроки.
- Повысить качество за счёт снижения эксплуатационных рисков[14].
Часто параллельно проводится анализ целесообразности и оценка стоимости (напр. по модели COCOMO).
Программные комплексы не способны воспроизводить человеческое мышление полностью: даже наиболее продвинутые системы ограничены заранее определёнными функциями и моделями поведения, и реализуют только часть «человеческой» логики. Для сложных задач может требоваться более мощное аппаратное обеспечение.
На этом этапе формализуется описание поведения и свойств будущего программного продукта: бизнес-требования, взаимодействие с пользователем, приоритеты требований.
Используются формальные методы:
- Прецедент
- Пользовательская история
Первые из них более формальны и строгие.
Архитектура ПО объединяет инфраструктурные, программные и информационные составляющие, определяет логику работы и способы интеграции, а также структуру и взаимосвязи компонент. Архитектор программного обеспечения играет ключевую роль в проектировании комплексных решений.
Классические средства моделирования архитектуры — диаграммы классов, данных, развертывания, последовательностей.
Программные средства для проектирования — CASE (напр., Enterprise Architect, Microsoft Visio for Enterprise Architects).
Программирование — собственно реализация проектных решений в коде. Сложность этапа во многом определяется выбранным языком и архитектурой.
В классической схеме выделяют этапы:
- Разработка инфраструктуры — организационная проработка элементов, образующих фундамент приложения.
- Адаптация пакета — детальный анализ и настройка компонентов сторонних пакетов (при необходимости).
- Создание интерактивных модулей — детализация пользовательских сценариев и их реализация, а также юнит- и интеграционное тестирование.
- Создание пакетных модулей — использование техник, таких как диаграммы потоков, структурные схемы и др., для наглядного проектирования.
- Проектирование ручных процедур — подготовка инструкций и организационных процессов сопровождения[16].
Тестирование заключается в проверке соответствия функций продукта исходным требованиям. Практикуются модульные (юнит-тесты) и интеграционные тесты, итоговая приёмка.
Рекомендуется, чтобы тесты проводились независимыми специалистами или специальными отделами.
Согласно [Роджер С. Прессман], тестирование охватывает как логику внутренней реализации, так и внешние пользовательские сценарии. Важно привлекать реальных пользователей для проверки и сбора обратной связи. Эффективный процесс испытаний невозможен без регулярного взаимодействия с заказчиками[17].
Внедрение — реализация алгоритмов и спецификаций в виде исполняемых программ, библиотек или сервисов. Внедрение предполагает формализацию структуры программы, интерфейсов и потоков данных[18].
Документирование охватывает процесс разработки, архитектуру, бизнес-сценарии, диаграммы, тестовые процедуры, а также пользовательские и технические руководства.
Сопровождение — стадия доработки, исправления и расширения функций программного продукта. По данным исследований М. Лемана, порядка 2/3 времени проекта уходит именно на сопровождение[10].
Классически выделяются: «исправляющая» (устранение ошибок), «адаптивная» (добавление новых функций), «перфекционирующая» (оптимизация) и «превентивная» (адаптация к изменениям среды) формы сопровождения.
- Повышение прозрачности и контроля над проектом
- Оптимизация использования ресурсов
- Улучшение коммуникации между пользователями и разработчиками
- Обеспечение оценки результатов и достижения целей
- Помогает понять задачу и предметную область
- Повышает возможность повторного использования решений
- Облегчает сопровождение продукта
- Оптимизирует каждую фазу разработки
- Гарантирует заданный уровень качества конечного продукта
- Обеспечивает прогнозируемый жизненный цикл системы
- Повышает уверенность в соблюдении сроков
Модели и жизненный цикл разработки
Программная инженерия предлагает ряд моделей и жизненных циклов, призванных упорядочить процесс создания программных систем — от появления первоначальной идеи до вывода системы из эксплуатации[19].
Этапы типового жизненного цикла:
- Определение целей
- Анализ требований и проверка их выполнимости
- Общий дизайн
- Детализированный дизайн
- Программирование
- Модульное тестирование
- Интеграция
- Пользовательское тестирование и валидация
- Документирование
- Внедрение
- Сопровождение[20]
Каскадная модель (waterfall) — последовательное прохождение фаз: спецификация, проектирование, разработка, тестирование, внедрение, сопровождение[21].
Модель прототипирования относится к эволюционным моделям: часть решения быстро реализуется (прототип), согласуется с заказчиком, и в ходе доработок превращается в итоговый продукт[22].
Спиральная модель разработки (Boehm, 1986) — сочетает итеративный, прототипный и каскадный подход, концентрируясь на анализе рисков и постоянном уточнении требований. Используется поэтапная доработка продукта через циклы[23].
Разработка осуществляется по последовательным стадиям, на каждой результаты уточняются и согласуются с заказчиком. Подходит для проектов, где требования формулируются по мере работы.
Преимущества:
- Выявление ошибок на ранних этапах
- Итеративность позволяет точнее прогнозировать сроки и реализовывать проект по частям
Итеративно-инкрементная: развитие системы через последовательные, частичные улучшения и дополнения[24].
Использует методы структурного программирования и проектирования. Преимущества — чёткость представления процессов и данных, иерархичность. Основные недостатки — риск дублирования данных и сложность поддержания больших систем[25].
ООП — уделяет ключевое внимание понятию класса; способствует повторному использованию кода, упрощает автоматизацию проектирования, активно поддерживается средствами UML[26].
RAD — ускоренная инкрементальная методология на основе компонентных и CASE-технологий. Команда выпускает работоспособный продукт в краткие сроки (при хорошо определённых требованиях)[27].[28]
Concurrent development model — на разных стадиях задачи и компоненты разрабатываются параллельно, часто применяется для клиент-серверных и распределённых систем.
Rational Unified Process, RUP — адаптивный процесс, объединяющий гибко настраиваемые рабочие процессы, дисциплины и артефакты. Стандарт проводится по осям времени (фазы, итерации) и дисциплинам (логику задач), является базой для всевозможных корпоративных процессов[29].[30]
Продукт
Программное обеспечение стало неотъемлемой частью современной жизни, стимулирует бизнес, научные исследования и развитие технологий.
Основа — программы, данные и документация, составляющие электронные продукты для решения реальных задач. Программные продукты делятся на:
- Генерические (тиражируемые)
- Индивидуальные («под заказ»)
К ключевым свойствам относятся: модифицируемость, надёжность, эффективность, качество интерфейса и документации.
Специфика программной инженерии
Программная инженерия — междисциплинарная область, использующая методы инженерии и точных наук для достижения качества ПО.
Важные концепции (корректность, сложность алгоритмов) строго формализуются с помощью математики; подход известен как «формальные методы».
ПО проектируется и выстраивается поэтапно — как на конвейере, что позволяет стандартизировать процесс и повысить качество и предсказуемость.
Разработка масштабных систем требует планирования бюджета, сроков, ресурсообеспечения и управления специалистами.
См. также
Примечания
Литература
- Программная инженерия (шестое издание), И. Соммервиль. Addison Wesley.
- Прессман Р. С.: Инженерия программного обеспечения. Практический подход (информация на английском), McGraw Hill Higher Education, шестое издание, с. 50–51.
Ссылки
- «Is software engineering actually engineering?» — статья в The Iron Warrior, Engineering Society University of Waterloo.
- Алгоритмы без колонизации: подход к мультикультурной разработке ПО — журнал Humanization Technology, 2020, Г. Реймондо.


