Под технологией программирования понимается [4] совокупность знаний о способах и средствах достижения целей в области программного обеспечения ЭВМ, в том числе и таких, которые ранее никем не достигались.
В широком смысле технология разработки программного обеспечения должна обеспечивать последовательный подход к созданию программных систем. Наиболее очевидная цель в разработке программного обеспечения состоит в соблюдении установленных заказчиком требований при реализации системы. Однако у заказчика редко имеются полные и последовательные определения требований. Обычно и заказчик и разработчик не до конца понимают проблему, и требования совершенствуются в процессе разработки системы. Необходимо отметить и факт изменения требований в течение жизненного цикла программной системы.
Изменения являются постоянным фактором разработки программного обеспечения. Для того чтобы преодолеть их разрушающий эффект, в качестве целей технологии разработки программного обеспечения принимаются следующие четыре свойства программных систем:
1. Модифицируемость. Необходимость модификации ПО обычно возникает по двум причинам: чтобы отразить в системе изменение требований или чтобы исправить ошибки, внесенные ранее в процессе разработки.
2. Эффективность системы подразумевает, что при функционировании оптимальным образом используются имеющиеся в ее распоряжении ресурсы: время и память.
3. Надежность системы ПО означает, что она должна предотвращать концептуальные ошибки, ошибки в проектировании и реализации, а также ошибки, возникающие при функционировании системы.
4. Понимаемость. Последняя цель технологии ПО - понимаемость - является мостом между конкретной проблемной областью и соответствующим решением. Для того чтобы система была понимаемой, она должна быть «прозрачной».
Цели технологии разработки программного обеспечения, рассмотренные выше, не могут лишь пассивно признаваться. Наоборот, по мере выполнения работ необходимо придерживаться определенного набора принципов, которые обеспечивают достижение этих целей. В качестве таких принципов обычно выделяют абстракцию, сокрытие информации, модульность, локализацию, единообразие, полноту и подтверждаемость.
Абстракция является одним из основных средств для управления сложными системами программного обеспечения. Суть абстракции состоит в выделении существенных свойств с игнорированием несущественных деталей. По мере декомпозиции решения на отдельные компоненты каждая из них становится частью абстракции на соответствующем уровне. Абстрагирование применяется и к данным, и к алгоритмам. На любом уровне абстракции могут фиксироваться абстрактные типы данных, каждый из которых характеризуется множеством значений и множеством операций, применимых к любому объекту данного типа.
Сокрытие или упрятывание информации имеет целью сделать недоступными детали, которые могут повлиять на остальные, более существенные части системы. Упрятывание информации обычно скрывает реализацию объекта или операции и, таким образом, позволяет фиксировать внимание на более высоком уровне абстракции. Кроме того, сокрытие проектных решений нижнего уровня оберегает стратегию принятия решений верхнего уровня от влияния деталей.
Абстракция и сокрытие информации способствуют модифицируемости и понимаемости систем программного обеспечения. На каждом уровне абстракции допускается применение лишь определенного набора операций и делается невозможным применение любых операций, нарушающих логическую концепцию данного уровня, за счет чего повышается надежность программной системы.
Модульность является следующим фундаментальным свойством, помогающим управлять сложностью систем программного обеспечения. Она реализуется целенаправленным конструированием. В самом общем плане модули могут быть функциональными (процедурно-ориентированными) или декларативными (объектно-ориентированными). Связность модулей определяется как мера их взаимной зависимости. В идеале должны разрабатываться слабо связанные модули. Другой мерой, применимой к модульности, является прочность, которая определяет, насколько сильно связаны элементы внутри модуля.
Локализация помогает создавать слабо связанные и весьма прочные модули. По отношению к целям технологии разработки программного обеспечения принципы модульности и локализации прямо способствуют достижению модифицируемости, надежности и понимаемости.
Абстракция и модульность считаются наиболее важными принципами, используемыми для управления сложностью систем программного обеспечения. Но они не являются достаточными, потому что не гарантируют получения согласованных и правильных систем. Для обеспечения этих свойств необходимо привлекать принципы единообразия, полноты и подтверждаемости.
Принципы технологии разработки программного обеспечения не должны применяться случайно - необходимо выполнять структуризацию системы определенным образом и, что самое важное, поскольку происходит деление системы на модули, применять согласованные критерии декомпозиции. Можно выделить три основных подхода к разработке программного обеспечения, обеспечивающие такие критерии: нисходящее структурное проектирование [15]; проектирование, структурированное по данным [27], и объектно-ориентированное проектирование [5].
Нисходящее структурное проектирование определяет декомпозицию системы путем оформления каждого шага этого процесса в виде модуля. Это приводит к созданию функциональных программных модулей.
Проектирование, структурированное по данным, является альтернативой нисходящей методологии. При этом сначала определяются структуры данных, а затем на их основе определяется структура программных модулей. Таким образом, здесь делается попытка сначала четко определить реализацию объектов, а затем сделать их структуру видимой в функциональных модулях, обеспечивающих операции над объектами.
Методы нисходящего проектирования императивны по своей природе. Они заставляют концентрировать внимание на операциях, мало заботясь о проектировании структур данных. Методы проектирования, основанные на структурировании по данным, находятся как бы на другом конце спектра. Они концентрируют внимание на объектах, а операции трактуют глобальным образом.
В идеале разработчикам программного обеспечения хотелось бы использовать подход, позволяющий строить решения прямо в соответствии с имеющимся представлением проблемы. Кроме того, как и в естественном языке, желательна сбалансированность объектов и операций на уровне принимаемых решений.
Такой подход получил название объектно-ориентированного [5]. Здесь учитывается важность трактовки объектов программного обеспечения как активных элементов, причем каждый объект наделен своим собственным набором допустимых операций. Легко убедиться, что объектно-ориентированная парадигма поддерживает основные принципы технологии разработки программного обеспечения.
Под жизненным циклом разработки программного обеспечения традиционно понимается упорядоченная совокупность этапов, обеспечивающих создание качественного программного продукта. В общем случае в жизненный цикл разработки включаются следующие стадии: техническое задание, эскизный проект, технический проект, рабочий проект и внедрение.
В литературе существует множество нареканий на несовершенство данного разбиения [22], но смысл его в целом достаточно ясен - борьба со сложностью процесса разработки программных продуктов за счет структуризации этапов и локализации на каждом из них только тех задач, которые могут и должны решаться именно здесь. Если перечисленные выше этапы укрупнить, останутся стадии проектирования, реализации и сопровождения.
Проектирование предполагает составление формальных и/или формализованных спецификаций.
Реализация - преобразование этих спецификаций в программный код (автоматическое и/или автоматизированное).
Сопровождение - тестирование разработанной системы, ее внедрение и последующую модификацию, которая, в свою очередь, может вернуть весь процесс к стадии проектирования (перепроектирование).
Ключевой стадией в жизненном цикле процесса разработки ПО является проектирование. Ошибки и просчеты, допущенные здесь, - самые «дорогие». Поэтому основные усилия в области технологии программирования направлены на автоматизацию проектирования программных комплексов. При этом базисными понятиями являются модель программы и модель системы.
Одну из таких моделей предлагает W/O (Warnier/Orr) методология. Она объединяет методологию Warnier по использованию логических структур данных и логических конструкций программ и систем и методологию DSSD (Data Structured System Development) Oppa, базисом которой является аксиома о логическом соответствии между эвристической структурой программ и данных, обрабатываемых этими программами. На практике такая: методология предполагает, что в распоряжении проектировщика системы имеется представительный набор процедурных шаблонов для достаточно широкого класса программируемых задач.
В настоящее время DSSD-методология «переросла» из методологии разработки программ в методологию разработки систем. При этом выделены явно уровень программирования (programming level) и системный уровень (system level). Применяются в DSSD два концептуальных представления - диаграммы входов (Entity diagrams), обеспечивающие определение системного контекста, и модифицированные W/O-диаграммы (Assembly-line Diagrams), специфицирующие функциональное развитие системы.
Следующим подходом к созданию моделей программ (по идее достаточно близким к W/O-методологии) является логическое моделирование Гэйна. Сам метод ориентирован на создание систем обработки данных. Логическая модель системы проектируется в процессе последовательного применения следующих семи этапов: описание природы предметной области с помощью диаграмм потоков данных (Data Flow Diagram); выделение первичной модели данных (списка элементов данных в каждом информационном узле); проверка того, что DFD действительно отражает структуру данных, хранимых в системе; сведение полученной на предыдущем этапе информации в двумерные таблицы, которые в дальнейшем нормализуются; коррекция DFD с учетом результатов нормализации предыдущего этапа; разбиение полученной в результате выполнения предыдущих этапов модели на «процедурные единицы» (procedure units), а также определение деталей каждой процедурной единицы. После выполнения этих этапов принимается решение о необходимости прототипирования системы на целевом языке.
И наконец, третьим в ряду подходов к созданию модели проектируемой программы является метод Йордана (Yourdon). Он включает два компонента: инструментальные средства и методики. Ориентирована методология Йордана на проектирование систем обработки данных. Под инструментальными средствами здесь понимаются различные диаграммы, используемые при описании моделей требований и моделей архитектуры проектируемой информационной системы. Самые известные из таких диаграмм - диаграммы потоков данных DFD. Однако их недостатком является отсутствие средств описания отношений между данными и их «поведения» во времени. Вот почему в инструментальные средства метода Йордана на сегодняшний день кроме DFD включены ERD-диаграммы (Entity Relationship Diagrams) и STD-диаграммы (State Transition Diagrams).
Методики в методе Йордана помогают перейти от бланка на бумаге и/или экранной формы к хорошо организованной системной модели. Первоначально эти методики базировались на традиционном top-down проектировании. В настоящее время здесь используется метод событийного разбиения (event partitioning). При этом сначала создается контекстная диаграмма верхнего уровня (top level context diagram), где определяются системные ограничения и интерфейсы с внешним «миром». Затем с помощью техники интервью формируется список событий из внешней среды, на которые система должна реагировать. Такой подход обеспечивает простой базис для формирования «сырой» DFD. Несколько DFD-реакций могут быть объединены в реакцию более высокого уровня. Критерием такого объединения является наличие узлов, связанных общими данными. По существу, событийное разбиение не что иное, как метод объектно-ориентированного проектирования.
Проблемы, возникающие при использовании метода ERD-диаграмм, связаны, прежде всего, с трудностями интеграции компонентов при разработке всей системы. Вот почему в последнее время этот метод был обобщен за счет введения интегрированной базы данных. При этом ERD-метод трансформируется в структурную методологию, основные этапы которой сводятся к разработке ERD (здесь выделяются как собственно сущности с их типами, так и связи, тоже с их типами); определению кардинальности (cardianality) - однозначности-многозначности типов связей; преобразованию ERD по определенным правилам в соответствующий файл и структуру БД. В процессе такого преобразования каждый тип сущности трансформируется в отношение, а тип связи - в особое (stand alone) отношение или объединяется с другими отношениями в зависимости от кардинальности типа связи. Разработка прикладных программ на основе сформированного файла и структуры базы данных является заключительным этапом в этом подходе.
Последним методом является метод структурного проектирования (Structured Design). Структурное проектирование сделалось действительно мощным и активно используемым на практике подходом за счет того, что к моделям и методам были добавлены оценки результатов проектирования. Здесь предлагаются все проектные решения располагать в 3-мерном пространстве (содержание - сложность - связность). И утверждается, что хорошими проектными решениями будут лишь те, которые при заданном содержании имеют минимальную сложность и максимальную связность. По существу, этот критерий отражает уже обсуждавшиеся выше понятия абстрагируемости, модульности, сокрытия информации, связности и т. п. Конкретным примером воплощения структурного подхода является «водопадная» или «каскадная» (waterfall) модель разработки систем ПО.
Технология программирования уже прошла достаточно долгий путь развития, и сейчас происходит переоценка ее фундаментальных исходных посылок. Первым кандидатом для такой переоценки стала традиционная точка зрения на процесс разработки программного обеспечения, как на процесс, основанный на понятии жизненного цикла. Растущее единодушие специалистов состоит в том, что данная точка зрения должна быть заменена такой, которая в большей степени соответствовала бы разработкам, поддерживаемым автоматизированными средами.