Лекция 1. Введение в программную инженерию

Основная задача курса — дать студентам разносторонний и по возможности полный обзор вопросов, из которых состоит предмет "программной инженерии" (software engineering). В западных университетах подобный курс обычно преподается одним из первых, и потому очень часто называется просто SE1 (Software Engineering 1st course). В нашей ситуации, учитывая, что курс будет читаться для студентов последних курсов и выпускников, мы будем преследовть несколько другие цели: дополнить и систематизировать знания, полученные студентами из уже прослушанных ими курсов. По этой причине некоторые вопросы мы только упомянем, сославшись на другие курсы, а другие, более редкие вопросы, постараемся осветить со всей возможной подробностью.

Темы курса:

Мы будем ориентироваться на перечень тем, определенных IEEE для экзамена software engineering professional (темы приведены в алфавитном порядке):

  1. Software Engineering Overview
  2. Software Configuration Management
  3. Software Construction and Implementation
  4. Software Design
  5. Software Engineering Tools & Methods
  6. Software Engineering Management
  7. Software Engineering Process
  8. Software Maintenance
  9. Software Quality
  10. Software Requirements
  11. Software Testing
  12. Software Professionalism and Engineering Economics

Основные определения

(занудное введение, без которого не обойтись), сформулированные в виде FAQ (Frequently Asked Questions):
  1. Что такое программное обеспечение (software)?
  2. Это программы, а также вся связанная с ними документация и конфигурационные данные, необходимые для корректной работы программы (т.е. не только программа). В конечном итоге, продаются не программы, а программные продукты, которые бывают двух типов: коробочные продукты (generic products or shrink-wrapped software) и заказные продукты (bespoke or customized products). Важная разница между ними заключается в том, кто ставит задачу (пишет спецификацию).

  3. Что такое программная инженерия?
  4. Программная инженерия — это инженерная дисциплина, которая связана со всеми аспектами производства ПО от начальных стадий создания спецификации до поддержки системы после сдачи в эксплуатацию. В этом определении есть две важные части:

    Программные инженеры применяют систематичные и организованные подходы к работе для достижения максимальной эффективности и качества ПО. Общепринято мнение, что неправильно выбранный подход должен отрицательно сказаться на качестве и сроках сдачи системы. Но подход надо выбирать с умом — во многих случаях неформальные, "легкие" процессы могут оказаться значительно эффективнее (например, в таких задачах, как написание web-based applications или e-commerce systems).

  5. В чем разница между программной инженерией (software engineering) и информатикой (computer science)?
  6. Информатика занимается теорией и методами компьютерных и программных систем, в то время как программная инженерия занимается практическими проблемами создания ПО. Естественно, инженер-программист обязан в каком-то объеме знать информатику (точно так же, как электрический инженер должен в каком-то объеме знать физику). Однако объем теоретических знаний у разных специалистов сильно разнится и может быть очень невысоким, что тем не менее не мешает решать некоторые задачи (те, что попроще).

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

  7. В чем разница между программной инженерией и системной инженерией (systems engineering)?
  8. Системная инженерия (а точнее — компьютерная системная инженерия, computer-based systems engineering, CBSE) занимается всеми аспектами создания и эволюции комплексных систем, в которых ПО играет заметную роль. Таким образом, программная инженерия является частью системной инженерии, наряду с созданием аппаратных платформ, созданием архитектуры, системной интеграцией и т.п. В системной инженерии основной упор приходится именно на системные вопросы, а не на составные части системы.

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

  9. Что такое программный процесс?
  10. Программный процесс — это набор действий и связанных с ними результатов, приводящих к созданию программного продукта. Мы будем выделять четыре основных фазы программного процесса:

  11. Что такое модель программного процесса?
  12. Модель программного процесса — это упрощенное описание программного процесса, представленное с некоторой точки зрения. Модели всегда являются упрощениями: all models are wrong; some models are useful (E. Deming). Некоторые примеры типов моделей программного процесса:

    Есть несколько традиционных моделей разработки ПО:

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

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

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

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

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

  15. Что такое методы программной инженерии?
  16. Метод программной инженерии — это структурный подход к созданию ПО, нацеленный на создание эффективного продукта наиболее прибыльным (рентабельным, cost-effective) путем.

    Тема развивается с 1970х: структурный анализ Тома ДеМарко (1978), JSD Джексона (1983). Эти и другие методы тех времен были ориентированы на идентификацию основных функций системы; функционально-ориентированные методы до сих пор популярны. Как это ни смешно, очень часто их применяют неосознанно.

    В 1980х гг. эти методы были дополнены всякой объектностью: Буч (1994), Рамбо (1991). Со временем эти методы были объединены в UML (до хрена книжек начиная с 1997 г).

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

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

  17. Что такое CASE (Computer-Aided Software Engineering)?
  18. Понятие CASE включает в себя широкий комплекс программ, предназначенных для поддержки процессов создания программного продукта, включая анализ требований, моделирование, отладку и тестирование. Большинство современных методов поддержаны соответствующими CASE-средствами.

    Любопытное разделение: CASE-средства, поддерживающие анализ и проектирование, иногда называют CASE-средствами верхнего уровня (upper-CASE tools), а средства, поддерживающие реализацию и тестирование, такие как отладчики, средства анализа системы, генераторы тестов и редакторы программ, называют средствами нижнего уровня (lower-CASE tools).

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

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

    Большинство свойств программы можно обобщить в несколько категорий (см. таблицу):

    Характеристика продукта
    Описание
    Сопровождаемость
    (maintainability)
    Система должна быть написана с расчетом на дальнейшее развитие. Это критическое свойство системы, т.к. изменения ПО неизбежны вследствие изменения бизнеса.
    Надежность
    (dependability)
    Надежность включает в себя отказоустойчивость, безопасность и защищенность. Надежное ПО не должно приводить к физическому или экономическому ущербу в случае сбоя системы.
    Эффективность
    (efficiency)
    ПО не должно впустую тратить системные ресурсы, такие как память или процессорное время. Поэтому эффективность включает в себя отзывчивость, время процессора, утилизацию памяти и т.п.
    Удобство использования
    (usability)
    ПО должно быть легким в использовании, причем именно тем типом пользователей, на которых рассчитано приложение. Это включает в себя интерфейс пользователя и адекватную документацию.

  21. Какие основные трудности стоят перед программной инженерией?
  22. Всего-то три основные трудности:

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

Профессионализм и этика в работе программиста

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

В таких вопросах крайне важную роль должны играть профессиональные общества и организации. Такие общества, как ACM, IEEE и British Computer Society регулярно публикают кодексы профессионального поведения или кодексы этики. Все члены этих обществ обязываются их соблюдать. Так, ACM и IEEE произвели на свет ACM/IEEE Code of Ethics.

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

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

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

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

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