Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ГЛАВА_4.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
1 Мб
Скачать
☆

Контрольные вопросы

1. Каково назначение этапа управления требованиями к программно­му продукту в жизненном цикле разработки программного продукта?

2. Какие действия включает в себя работа по управлению требовани­ями?

3. Какие цели преследует работа по управлению требованиями?

4. На какие категории можно разделить все требования при определе­нии их приоритетов?

5. В какой очередности следует реализовывать требования к програм­мному продукту?

6. Какие требования относятся к функциональным и нефункциональ­ным?

7. Какие действия включает в себя цикл формирования требований к программному продукту?

8. Какие цели преследует анализ первичных требований заказчика?

9. Какие действия выполняются при структурировании требований заказчика?

10. Какова роль прототипа при формировании требований к програм­мному продукту?

11. Какие преимущества обеспечивает прототип?

12. Почему требования в спецификации требований должны быть од­нозначными?

13. Какие метрики собирают на этапе управления требованиями?

14. Какие методы, стандарты и шаблоны используют на этапе управ­ления требованиями?

ПРОЕКТИРОВАНИЕ ПРОГРАММНОГО ПРОДУКТА

Общая характеристика и компоненты проектирования

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

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

название компоненты — ее уникальное имя;

тип компоненты — ее сущность (подсистема, процедура, про­цесс, элемент данных и т.д.);

функция — выполняемые компонентой действия;

зависимости — описание взаимосвязей с другими компонен­тами;

интерфейсы — описание методов взаимодействия с другими

компонентами;

ресурсы — описание необходимой аппаратной, библиотечной

или другой поддержки;

обработка — описание алгоритма выполнения функции;

данные — описание внутренних структур данных.

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

Результаты проектирования представляются в виде описания компонент проектирования по определенному набору атрибутов.

Эволюция разработки программного продукта

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

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

По мере того как вычислительные машины становились все мощнее и надежнее, значение программного обеспечения осоз­навалось- все большим числом ученых и практиков. Важнейший прорыв произошел в конце 1950-х годов, когда появились языки программирования высокого уровня — Fortran, Algol и др. Их по­явление было обусловлено прежде всего тем, что написание про­грамм без таких языков становилось все более сложной задачей. Решив текущие проблемы, эти языки создали новые. Ускорив и упростив программирование, они существенно расширили круг задач, решаемых с помощью ЭВМ. Появление новых задач, более сложных, чем решавшиеся раньше, привело к тому, что име­ющихся средств снова стало недостаточно для успешного их ре­шения.

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

В сложившейся ситуации усилия программистов были сосредо­точены прежде всего на создании новых языков программирова­ния. Появился язык Cobol, дающий возможность решать задачи обработки экономической информации. Он создавался таким об­разом, чтобы программа на нем выглядела почти как текст на английском языке. Появился язык PL/I, объединивший в себе все возможности, которые только могут иметь языки программиро­вания.

Языки Fortran, Algol, PL/I поддерживают процедурный стиль программирования. Программа разрабатывается в терминах тех действий, которые она выполняет. Основной единицей програм­мы является процедура. Процедуры вызывают другие процедуры, все вместе они работают по определенному алгоритму, который ведет к решению задачи. Алгоритм — это точная последователь­ность действий для получения необходимого результата.

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

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

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

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

Одной из наиболее широко применяемых методик программи­рования стал структурный подход к программированию. Создате­лем его считается Э. Дейкстра (Е. Dijkstra). Фактически структур­ный подход к программированию — это первая законченная ме­тодика программирования. Законченной ее можно назвать пото­му, что структурное программирование предлагает путь от задачи до ее воплощения в программе. Структурное программирование оказало огромное влияние на развитие программирования. Этот метод, который применялся очень широко в практическом про­граммировании, и по сей день не потерял своего значения для определенного класса задач.

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

использование процедурного стиля программирования;

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

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

1. Прочитать адрес.

2. Сверить адрес с базой имеющихся адресов.

3. Если результат проверки положителен, напечатать «Да», в противном случае напечатать «Нет».

Такая запись один к одному отображается в программе на язы­ке высокого уровня, например на Pascal или С.

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

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

Структурное программирование поддерживалось языками про­граммирования, появившимися в конце 1960-х годов (Pascal, Algol-68, Fortran и др.). Именно к тому времени было осознано значение программного обеспечения при решении задач с помощью вычис­лительной техники. Эти языки поддерживали разнообразные вло­женные процедуры, разные способы передачи параметров.

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

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

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

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

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

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

Объектно-ориентированный подход к программированию свя­зывают прежде всего с языками программирования, такими как Smalltalk, C++, Java и т.д. Эта позиция имеет существенные осно­вания. Поскольку языки являются главными инструментами объек­тно-ориентированного программирования, именно при их разра­ботке появилось большинство тех идей, которые и составляют основу объектно-ориентированного метода в настоящее время.

Накопление новых идей шло в течение примерно 10 лет, начи­ная с конца 1960-х годов. К концу 1970-х годов переход на новый уровень абстракции стал свершившимся фактом в академических кругах. Потребовалось еще около 10 лет, чтобы новые идеи про­никли в промышленность. Пожалуй, первым шагом на пути со­здания собственно объектной модели следует считать появление абстрактных типов данных.

Первым на необходимость структуризации систем по уровням абстракции указал Э.Дейкстра. Идея инкапсуляции (скрытия ин­формации) была высказана Д. Парнасом. Позднее был разработан механизм абстрактных типов данных, который был дополнен С.Хоором в его теории типов и подтипов.

Считается, что первой полной реализацией абстрактных типов данных в языках программирования является язык Simula, кото­рый, в свою очередь, опирается на языки Modula, CLU, Euclid и др. Первым «настоящим» объектно-ориентированным языком программирования принято считать Smalltalk, разработанный в лаборатории компании «Ксерокс» в Паоло-Альто. (Многие по-прежнему считают его единственным настоящим объектным язы­ком программирования.) Затем появились (и продолжают появ­ляться) другие объектно-ориентированные языки, которые оп­ределяют современное состояние программирования. Наиболее рас­пространенными из них стали C++, CLOS, Eiffel, Java.

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

Появление объектно-ориентированного метода произошло на основе всего предыдущего развития методов разработки программ­ного обеспечения, а также многих других отраслей науки. Амери­канский эксперт в области программирования Гради Буч (Grady Booch) помимо развития языков программирования отмечает сле­дующие достижения, которые способствовали возникновению объектно-ориентированного подхода к проектированию систем.

1. Развитие вычислительной техники, в частности аппаратная поддержка основных концепций операционных систем и постро­ение функционально-ориентированных систем. При проектиро­вании вычислительных машин использование понятия объекта началось с исследований по нефоннеймановской архитектуре. Попытки сократить семантический разрыв между низкоуровне­вой архитектурой традиционных процессоров и высокоуровневы­ми понятиями операционных систем предпринимались при пост­роении таких систем, как Барроус, Intel i432, IBM/38 и др. Тесно связанные с ними разработки объектно-ориентированных опера­ционных систем начались, пожалуй, с проекта THE под руковод­ством Э. Дейкстры, были продолжены в системах iMAX для Intel i432 и др. Сравнительно недавние проекты Cairo Microsoft и Taligent Pink (хотя и остановившиеся на исследовательском этапе) — это также проекты объектно-ориентированных операционных систем.

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

3. Создание теории построения и моделирования систем управления базами данных, которая внесла в объектное программиро­вание идеи построения отношений между объектами. Моделирование данных с помощью отношений между объектами было впер- ; вые предложено П. Ченом (P. Chen) в методе ER-моделирования.

В этом методе модель данных строится в виде объектов (сущнос­тей), их атрибутов и отношений между ними.

4. Исследования в области искусственного интеллекта, позво­лившие лучше осознать механизмы абстракции. Теория фреймов, предложенная М. Минским для представления реальных объектов «в системах распознавания образов, дала мощный импульс для развития не только систем искусственного интеллекта, но и ме­ханизмов абстракции в языках программирования.

5. Развитие философии и теории познания. Объектно-ориенти­рованное построение систем — это определенный взгляд на моде­лируемый реальный мир. Именно в этом аспекте философия и теория познания оказали сильное влияние на объектную модель. Еще древние греки рассматривали мир в виде объектов или про­цессов. Декарт выдвинул предположение, что для человека есте­ственным представляется объектно-ориентированное рассмотре­ние окружающего мира. М. Минский предположил, что разум проявляется как взаимодействие агентов, не умеющих по отдель­ности мыслить.

Теория архитектуры и строительства, выдвинувшая концеп­цию образцов или шаблонов, активно используется в последние годы в области объектно-ориентированного анализа (ООА) и объектно-ориентированного проектирования (ООП).

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

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

Несмотря на провал при попытке достичь основной цели, опыт разработки CASE-средств дал очень много для развития методов программирования. Небольшая часть систем используется напря­мую (например, генераторы компиляторов lex и уасс), часть идей была использована при создании современных средств быстрой разработки программ (RAD — Rapid Application Development), таких как JBuilder, Delphi, Powerbuilder и др.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]