МИНИСТЕРСТВО ОБРАЗОВАНИЯ РЕСПУБЛИКИ КАЗАХСТАН

 Некоммерческое акционерное общество

АЛМАТИНСКИЙ УНИВЕРСИТЕТ ЭНЕРГЕТИКИ И СВЯЗИ

  

 

Н.В.Сябина  

ТЕХНОЛОГИИ ПРОГРАММИРОВАНИЯ

Учебное пособие

 

 

Алматы 2012

УДК 004.412/416.2 (075.8)

ББК 32.973-018 я 73

С99 Технологии программирования:

Учебное пособие/Н.В.Сябина;

АУЭС, Алматы, 2011. -  99  с.

Табл.5, Ил.30, Библиогр.– 42 назв.

  

ISBN 978-601-7307-07-03

                

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

Учебное пособие предназначено для студентов специальности 5В070200 - Автоматизация и управление.

 

ББК 32.973-018 я 73

  

РЕЦЕНЗЕНТЫ:   КазНТУ, канд.тех.наук, доцент Байматаева Ш.М., АУЭС, канд.тех.наук, доцент Аманбаев А.А.

 

         Печатается по плану издания Министерства образования Республики Казахстан  на 2011 г.

  

ISBN 978-601-7307-07-03

 

 

                 ©        НАО «Алматинский университет энергетики и связи», 2012

 

Содержание 

Введение                                                                                                            4

1 глава. Введение в технологию программирования. Основные понятия и

подходы                                                                                                            5

1.1 Понятие технологии программирования и ее роль                           5

1.2 Основные этапы развития технологии программирования              5

1.3 Краткий обзор наиболее известных технологий                             11

2 глава. Особенности разработки сложных программных систем                14

2.1 Основные принципы разработки                                                     14

2.2 Жизненный цикл программного обеспечения                                 16

2.3 Качество программного обеспечения                                             26

2.4  Роль модулей в обеспечении технологичности                              27

2.5  Основные подходы к разработке программного обеспечения      32

2.6 Стили оформления программы                                                        43

         2.7 Программирование без ошибок                                                       46

3 глава. Требования и исходные данные к разработке программного

обеспечения                                                                                                     49

3.1 Классификация программного обеспечения по функциональному

признаку                                                                                                          49

3.2 Эксплуатационные требования к программному обеспечению      51

3.3 Постановка задачи                                                                            52

3.4 Анализ требований и определение спецификаций                           60

4 глава. Особенности проектирования программного обеспечения при различных подходах                                                                                                                          65

4.1 Структурный подход                                                                       65

4.2 Объектный подход                                                                           68

5 глава. Пользовательские интерфейсы                                                          74

5.1 Основные понятия                                                                            75

5.2 Виды пользовательских интерфейсов                                              76

5.3 Типы пользовательских интерфейсов                                              80

5.4 Особенности разработки пользовательских интерфейсов              82

6 глава. Тестирование и отладка программных продуктов                            87

6.1 Основы тестирования программного обеспечения                         87

6.2 Отладка программного обеспечения                                               90

7 глава. Составление программной документации                                         92

Заключение                                                                                                      94

Приложение А                                                                                                 95

Список литературы                                                                                        97


Введение 

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

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

Изложение материала учебного пособия строится в соответствии с рабочей программой одноименной дисциплины, читаемой в Алматинском университете энергетики и связи для специальности 5B070200 – «Автоматизация и управление».

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

В учебном пособии не рассматриваются вопросы программирования на конкретном языке.

Материал сопровождается сравнительно простыми примерами, иллюстрациями и таблицами.

 

1 глава. Введение в технологию программирования. Основные понятия и подходы

 

1.1 Понятие технологии программирования и ее роль

Под технологией программирования понимают совокупность методов и средств, используемых в процессе разработки программного обеспечения [16]. Она представляет собой набор технологических инструкций, включающих:

1)   указание последовательности выполнения технологических операций;

2)    перечисление условий, при которых выполняются опера­ции;

3)   описания самих операций с определением исходных данных, результатов, инструкций, нормативов, стандартов, кри­териев и методов оценки.

4)   оп­ределяет способ описания проектируемой системы (модели), исполь­зуемой на конкретном этапе разработки.

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

В литературе имеются и другие, несколько отличающиеся, определения технологии программирования [14]. Кроме того, используется близкое к технологии программирования понятие программной инженерии (software engineering), определяемой как систематический подход к разработке, эксплуатации, сопровождению и изъятию из обращения программных средств.

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

 

1.2 Основные этапы развития технологии программирования

Среди основных этапов развития технологий программирования выделяют «стихийное» программирование, структурный, объектный и компонентный подходы к программированию [16].

 

1.2.1 Этап «стихийного» программирования.

Характерной особенностью периода от момента появления первых ЭВМ до середи­ны 60-х годов XX века является то, что сформулиро­ванные технологии программирования практически отсутствовали, а само программирование было искусством.

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

В результате появления ассемблеров вместо двоичных ко­дов стали использовать символические имена данных и мнемоники кодов опера­ций, а программы стали более «читаемыми». Именно в этот период зародилась ставшая впоследствии фундаментальной для технологии программирования концепция модульного программирования [14], ориентированная на преодоления трудностей программирования в машинном коде. Создание языков программирования высоко­го уровня (FORTRAN, ALGOL) суще­ственно упростило программирование вычисле­ний, снизив уровень детализации операций, что позволило увеличить сложность программ. Из первых языков модульного программирования сохранился только FORTRAN благодаря грандиозной библиотеке накопленных программных модулей.

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

 

Рисунок 1.1 - Архитектура программ с глобальной и локальной областями данных

В начале 60-х годов XX века раз­разился «кризис программирова­ния»: разработчики сложного программного обеспече­ния срывали все сроки завершения проектов: проект устаревал раньше, чем был готов к внедрению, его стоимость увеличивалась, в ре­зультате многие проекты так никогда и не были завершены. Все это было вызвано несовершенством технологии программирования. Использование разработки «снизу-вверх» при отсутствии четких моделей описания подпрограмм и методов проектирования превращало создание программ в непростую задачу. Интерфейсы программ получались сложными, а при сборке программного продукта выявлялось большое количество ошибок со­гласования, исправление которых требовало серьезного изменения уже разработанных частей программ. При этом в программу часто вносились новые ошибки, в результате чего процесс тестирования и отладки программ занимал более 80% времени разработки, если вооб­ще когда-нибудь заканчивался. Анализ причин возникновения ошибок позволил сформу­лировать новый подход к программированию - струк­турный.

 

1.2.2 Этап структурного программирования.

Структурный подход к программированию, который развивался на втором этапе развития технологий в 60-70 годы XX века, представляет собой совокупность рекомендуемых технологических приемов, охватывающих вы­полнение всех этапов разработки программного обеспечения. В его основе лежит декомпозиция сложных си­стем с целью последующей реализации в виде отдельных небольших (до 40-50 операторов) подпрограмм, позже названная процедурной декомпозицией. Структурный подход требовал представления задачи в виде иерархии подзадач простейшей структуры, а проектирование осуще­ствлялось «сверху-вниз» и подразумевало реализацию общей идеи. Были введены ог­раничения на конструкции алгоритмов, рекомендованы формальные моде­ли их описания, а также специальный метод проектирования алгоритмов - метод пошаговой детализации. Принципы структурного программирования были заложены в основу процедурных языков программирования, которые включали основные «структурные» операторы передачи управле­ния, поддерживали вложение подпрограмм, локализацию и ограничение области «видимости» данных (PL/1, ALGOL-68, Pascal, С). Дальнейший рост сложности и размеров разрабатываемого программно­го обеспечения потребовал развития структурирования данных, в языках появляется возможность определения пользовательских типов данных [1].

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

Связи между модулями осуществлялись через спе­циальный интерфейс, в то время как доступ к реализации модуля (телам под­программ и некоторым «внутренним» переменным) был запрещен. Эту техноло­гию поддерживают современные версии Pascal, С, C++, Ада и Modula.

 

Рисунок 1.2 – Архитектура программы при структурном подходе

 

Разработка программ несколькими программистами существенно упростилась: модули разрабатывались независимо друг от друга и могли использоваться без изменений в других разработках, а их взаимодействие обеспечи­валось через специально оговоренные межмодульные интерфейсы. Структурный подход в сочетании с модульным программированием позволяет получать надежные программы, размером не более 100 000 операторов. Существенным недостатком является тот факт, что ошибка в интерфейсе при вы­зове подпрограммы выявляется только при выполнении программы (из-за раздельной компиляции модулей), а при увеличении размера программы возрастает сложность меж­модульных интерфейсов, поэтому предусмотреть взаимовли­яние отдельных частей программы становится практически невозможно. Поэтому для разработки программного обеспечения большого объема было предложено использовать объектный подход.

 

1.2.3 Этап объектного программирования.

На третьем этапе (80-е - 90-е годы XX века) был сформирован объектный подход к программированию.

Вообще говоря, 80-е годы характеризуются широким внедрением персональных компьютеров во все сферы человеческой деятельности и тем самым созданием обширного и разнообразного контингента пользователей программного обеспечения. Это привело к бурному развитию пользовательских интерфейсов и созданию четкой концепции качества программного обеспечения [14]. Развиваются методы и языки спецификации. Начинается бурный процесс стандартизации технологических процессов и, прежде всего, документации, создаваемой в этих процессах. Развивается концепция компьютерных сетей. На этом фоне и создаются предпосылки к формированию совершенно нового подхода к разработке сложного программного обеспечения с интуитивно понятным и удобным пользовательским интерфейсом.

Технология создания сложного программного обес­печения, основанная на представлении программы в виде совокупности взаимодействующих путем передачи сообщений программных объ­ектов, каждый из которых является экземпляром определенного клас­са, а классы образуют иерархию с наследованием свойств, была названа объектно-ориентированным программиро­ванием [16]. Объектная структура программы (см. рисунок 1.3) впервые была использована в языке имитационного моделирования сложных систем Simula, а затем использована в новых версиях универсальных языков программирования таких, как Pascal, C++, Modula, Java.

Рисунок 1.3 – Архитектура программы при объектно-ориентированном программировании

 

Достоинством объектно-ориентированного программирования является «естествен­ная» декомпозиция программного обеспечения, существенно облег­чающая разработку. Это приводит к более полной локализации данных и ин­тегрированию их с подпрограммами обработки, что позволяет вести практи­чески независимую разработку отдельных объектов программы. Кроме того, объектный подход предлагает новые способы организации программ, основанные на механизмах наследования, полиморфизма, компози­ции, наполнения, позволяющих конструировать из простых объек­тов сложные. В результате существенно увеличивается показатель повторного использования кодов и появляется возможность создания библиотек классов.

На основе объект­ного подхода были созданы среды, поддерживающие визуальное программирование (Delphi, C++ Builder, Visual C++), при использовании которого некоторая часть будущего продукта проектируется с применением визуальных средств добавления и настройки специальных библиотечных компонентов. В результате появляется заготовка будущей программы, в кото­рую уже внесены коды.

Использование объектного подхода имеет много преимуществ. Однако его конкретная реализация в объектно-ориентированных языках программи­рования таких, как Pascal и C++, имеет существенные недостатки: отсутствуют стандарты компоновки двоичных результатов компиляции объектов в единое целое даже в пределах одного языка программирования; изменение в реализации одного программного объекта связано с перекомпиляцией модуля и перекомпоновкой всего программного обеспечения, использующего данный объект. Таким образом, сохраняется объективная зависимость модулей программного обеспечения от адресов экспортируемых полей и методов, а также структур и форматов данных. Связи модулей нельзя разорвать, но можно стандартизировать их взаимодействие, на чем и основан компонентный подход к программированию.

 

1.2.4 Компонентный подход и CASE-технологии.

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

Компонентный подход предполагает построение программного обеспечения из отдельных компонентов, ко­торые взаимодействуют между собой через стандартизованные двоичные интерфейсы. В отличие от обычных объектов объекты-компоненты можно собрать в динамически вызываемые библиотеки или исполняемые файлы, распространять в двоичном виде (без исходных текстов) и использовать в любом языке программирования, поддерживающем соответствующую технологию [16]. Компонентный подход лежит в основе технологий, разработанных на базе COM (Component Object Model - компонентная модель объектов), и тех­нологии создания распределенных приложений CORBA (Common Object Request Broker Architecture - общая архитектура с посредником обработки запросов объектов), которые используют сходные принципы и разли­чаются лишь особенностями реализации.

Кроме того, отличительной особенностью современного этапа развития технологии программирования, является создание и внедре­ние автоматизированных технологий разработки и сопровождения про­граммного обеспечения, которые были названы CASE-технологиями (Computer-Aided Software/System Engineering - разработка программного обеспечения/программных систем с использованием компьютерной под­держки). Без средств автоматизации разработка достаточно сложного про­граммного обеспечения на настоящий момент становится трудно осуществи­мой: память человека уже не в состоянии фиксировать все детали, которые необходимо учитывать при разработке программного обеспечения. CASE-технологии поддерживают как структурный, так и объектный (компонентный) подходы к программированию [7].

 

1.3 Краткий обзор наиболее известных технологий

1.3.1 Технология СОМ.

Технология СОМ фирмы Microsoft является развитием техноло­гии OLE I (Object Linking and Embedding - связывание и внедрение объек­тов), которая использовалась в ранних версиях Windows для создания состав­ных документов. Она определяет общую концепцию взаимодей­ствия программ любых типов (библиотек, приложений, операционной сис­темы), т. е. позволяет одной части программного обеспечения использовать функции (службы), предоставляемые другой (см. рисунок 1.4).

Рисунок  1.4 – Компонентный подход. Технология СОМ

Модификация СОМ, обеспечивающая передачу вызовов между компьютерами, называется DCOM (Distributed COM - распределенная СОМ).

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

Классы СОМ поддерживают наследование интерфейсов, но не поддерживают наследования реализации, т. е. не наследуют код методов.

Объект всегда функционирует в составе сервера - динамической библи­отеки или исполняемого файла, которые обеспечивают функционирование объекта. Различают три типа серверов: внутренний, локальный и удаленный (например, MS Word является локальным сервером). Для обращения к службам клиент должен получить указатель на соот­ветствующий интерфейс. Взаимодействие клиента и сервера обеспечивается базовыми механизмами СОМ или DCOM, поэтому клиенту безразлично местонахождение объ­екта. При использовании локальных и удаленных серверов в адресном пространстве клиента создается proxy-объект - заместитель объекта СОМ, а в адресном пространстве сервера - СОМ-заглушка, соответствующая клиенту. Получив задание от клиента, заместитель упаковывает его параметры и, ис­пользуя службы операционной системы, передает вызов заглушке. Заглушка распаковывает задание и передает его объекту СОМ. Результат возвращается клиенту в обратном порядке.

На базе технологии СОМ и ее распределенной версии DCOM были разработаны компонентные технологии, решающие различные задачи разработ­ки программного обеспечения [16]. На возможностях COM базируется технология COM+, которая обеспечивает поддержку распределенных приложений на компонентной основе и предназначена для поддержки систем обработки транзакций [41].

Кроме того, к технологиям, реализующим компонентный подход, заложенный в СОМ, относятся:

а)     OLE-automation - технология создания программируемых приложений, обеспечивающая программируе­мый доступ к их внутренним службам (например, MS Excel поддерживает ее, предоставляя другим приложениям свои службы);

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

Преимуществами технологии ActiveX являются:

-   быстрое написание кода;

-   открытость и мобильность;

-   возможность написания приложений с использованием знакомых средств разработки (Visual Basic, Visual C++, Borland Delphi, Borland C++, Java);

-   большое количество существующих бесплатных программных элементов ActiveX;

-   стандартность;

в)    MTS (Microsoft Transaction Server - сервер управления транзакциями) - технология, обеспечивающая безопасность и стабильную работу распреде­ленных приложений при больших объемах передаваемых данных;

г)     MIDAS (Multitier Distributed Application Server - сервер многозвенных распределенных приложений) - технология, организующая доступ к данным разных компьютеров с учетом балансировки нагрузки сети.

 

1.3.2 Технология CORBA.

Технология CORBA, разработанная группой компаний OMG (Object Management Group - группа внедрения объектной технологии про­граммирования), реализует подход аналогичный СОМ на базе объектов и интерфейсов CORBA.

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

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

                                 

2 глава. Особенности разработки сложных программных систем

 

2.1 Основные принципы разработки

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

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

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

В природе существует еще один вид иерархии - иерархия «простое-сложное» или иерархия развития (усложнения) систем в процессе эволюции. В этой иерархии любая функционирующая система является результатом развития более простой системы. Именно этот вид иерархии реализуется механизмом наследования объектно-ориентированного программирования.

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

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

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

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

 

Рисунок 2.1 – Соотношение абстрактного и конкретного в описании блоков

при блочно-иерархическом подходе

 

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

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

Важную роль играют следующие прин­ципы:

а) непротиворечивость - контроль согласованности элементов;

б) полнота - контроль на присутствие лишних элементов;

в) формализация - строгость методического подхода;

г) повторяемость - необходимость выделения одинаковых блоков для
удешевления и ускорения разработки;

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

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

Достоинства блочно-иерархического подхода:

1)       возможность создания сложных систем;

2)       упрощение проверки работоспособности от­дельных блоков и системы в целом;

3)       обеспечение возможности модернизации систем.

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

 

2.2 Жизненный цикл программного обеспечения

 

2.2.1 Состав процессов жизненного цикла программного обеспечения.

Жизненным циклом программного обеспечения называется период от момента появления идеи создания некоторого программного обеспечения до момента завершения его поддержки фирмой-разработчиком или фирмой, выполняющей сопровождение [32].

Жизненный цикл охватывает довольно сложный процесс создания и использования ПО (software process). Этот процесс может быть организован по-разному для разных классов ПО и в зависимости от  особенностей коллектива разработчиков.

Состав процессов жизненного цикла регламентируется международным стандартом ISO/IEC 12207: 1995 «Information Technologe - Software Life Cycle Processes» («Информационные технологии - Процессы жизненного цикла программного обеспечения»). В стандарте описывается структура жизненного цикла программного обеспечения, определяются его процессы, не конкретизируя в деталях их реализацию.

Процесс жизненного цикла – это совокупность взаимосвязанных действий, преобразующих некоторые входные данные в выходные. На рисунке 2.2 представлены процессы жизненного цикла по указанному стандарту. Согласно этой структуре процессы разработки и сопровождения программного обеспечения относятся к основным процессам [16]. Условно выделяют следующие основные этапы разработки программного обеспечения:

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

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

в) проектирование - определяются подробные спецификации разрабатываемого программного продукта, выполняется проектирование общей структуры, декомпозиция компонентов и проектирование компонентов. Результат - детальная модель разрабатываемого ПО со спецификациями компонен­тов всех уровней.

г) реализация - процесс поэтапного напи­сания кодов программы на выбранном языке программирования (кодирование), их тестирование и отладка.

 

 

Рисунок 2.2 – Структура процессов жизненного цикла программного обеспечения

 

Сопровождение - это процесс создания и внедрения новых версий программного обеспечения.

Причинами выпуска новых версий могут служить:

- необходимость исправления ошибок, выявленных в процессе эксплуа­тации предыдущих версий;

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

- изменение среды функционирования, (появление новых тех­нических средств и/или программных продуктов, с которыми взаимодейст­вует сопровождаемое программное обеспечение);

- в программный продукт вносят необходимые изменения, которые могут потребовать пересмотра уже принятых проектных решений.

С изменением модели жизненного цикла ПО роль этого этапа существенно возросла, так как продукты теперь создаются итерацион­но: сначала выпускается сравнительно простая версия, затем следующая с большими возможностями, затем следующая и т. д. Поэтому в соответствии со стандартом ISO/IEC 12207 этап сопровождения был выделен в отдельный процесс жизненного цикла.

 

2.2.2 Модели жизненного цикла программного обеспечения.

На протяжении последних тридцати лет в программировании сменились несколько моделей жизненного цикла программного обеспечения [14]. Каждой из моделей соответствует определенная стратегия конструирования ПО [25]. Модели в процессе эволюции усложнялись и совершенствовались.

В 1970 году Уинстон Ройс предложил схему разработки, которая активно использовалась в течение последующих 15 лет (1970-1985). Каскадная схема разработки ПО предполагала, что переход на следующую стадию осуществляется только после того, как полностью будут завершены проектные операции предыдущей стадии и получены все исходные данные для следующей ста­дии (см. рисунок 2.3).

Рисунок 2.3 – Каскадная схема разработки программного обеспечения

 

Эту модель в разных источниках часто называют классическим жизненным циклом [25] или водопадной моделью [14].

Достоинствами такой схемы являются:

1) получение плана и временного графика по всем этапам проекта;

2) простота планирования процесса разработки;

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

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

Однако каскадная схема имеет недостатки:

1) реальные проекты часто требуют отклонения от стандартной последовательности шагов;

2) цикл основан на точной формулировке исходных требований к ПО;

3) результаты проекта доступны заказчику только в конце работы.

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

Каскадной (водопадной) схеме соответствует стратегия конструирования называемая однократным проходом или водопадной стратегией.

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

При макетировании модель может принимать одну из трех форм:

1) бумажный макет или макет на основе компьютера (изображается человеко-машинный диалог);

2) работающий макет (выполняется некоторая часть требуемых функций);

3) существующая программа (впоследствии характеристики программы должны быть улучшены).

Макетирование основывается на многократном повторении итераций, в которых участвуют заказчик и разработчик (см. рисунок 2.4).

Макетирование начинается со сбора и уточнения требований к программе. Разработчик и заказчик встречаются и определяют все цели ПО, устанавливают, какие требования известны, а какие предстоит доопределить. Затем выполняется быстрое проектирование, причем внимание сосредотачивается на тех характеристиках программного обеспечения, которые должны быть видимы пользователю. Быстрое проектирование приводит к построению макета.

Рисунок 2.4 - Макетирование

 

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

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

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

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

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

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

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

Рисунок 2.5 – Схема разработки программного обеспечения с промежуточным контролем

 

Инкрементная модель в отличие от макетирования позволяет получать на каждой итерации работающий продукт. Примерами современной реализации инкрементного подхода могут служить  технология быстрой разработки приложений (RAD-технология) и экстремальное программирование ХР, предложенное Кентом Беком в 1999 году [5].

В конце 1980-х годов Германией и США независимо друг от друга была разработана концепция V-образной модели - вариации каскадной модели, в которой задачи разработки идут сверху вниз по левой стороне буквы V, а задачи тестирования — вверх по правой стороне буквы V (см. рисунок 2.6). Внутри V проводятся горизонтальные линии, показывающие, как результаты каждой из фаз разработки влияют на развитие системы тестирования на каждой из фаз тестирования.

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

Немецкая V-модель была разработана аэрокосмической компанией IABG в Оттобрунне для Министерства обороны Германии и летом 1992 была принята немецкой федеральной администрацией для гражданских нужд. Американская V-Model (VEE) была разработана национальным советом по системной инженерии для спутниковых систем, включая оборудование, программное обеспечение и взаимодействие с пользователями. Современной версией V-Model является V-Model XT, которая была утверждена в феврале 2005 года и используется для управления процессом разработки программного обеспечения для немецкой федеральной администрации. Сейчас она является стандартом для немецких правительственных и оборонных проектов, а также для производителей программного обеспечения в Германии. V-Model представляет собой скорее набор стандартов в области проектов, касающихся разработки новых продуктов.

Рисунок 2.6 – Схема разработки программного обеспечения с использованием V-образной модели

 

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

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

Для преодоления проблем моделей итеративной разработки в 1988 году Барри Боэмом была предложена спиральная схема (см. рисунок 2.7).

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

 

Рисунок 2.7 – Спиральная схема разработки программного обеспечения

 

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

а)   I итерация: специфицируется, проектируется, реали­зуется и тестируется интерфейс пользователя;

б)   II итерация:  добавляется некото­рый ограниченный набор функций;

в)   III N- итерации:  рас­ширяется функционал продукта.

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

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

1)   сократить время до появления первых версий программного продукта;

2)   заинтересовать большое количество пользователей, обеспечивая быстрое продвижение следующих версий продукта на рынке;

3)   ускорить формирование и уточнение спецификаций за счет появления практики использования продукта;

4)   уменьшить вероятность морального устаревания системы за время разработки.

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

Спиральная модель является классическим примером применения эволюционной стратегии конструирования.

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

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

Достоинства компонентно-ориентированной модели:

1) уменьшает на 30% время разработки программного продукта;

2) уменьшает стоимость программной разработки до 70%;

3) увеличивает в 1,5 раза производительность разработки.

Альтернативой спиральной и каскадной моделям жизненного цикла является модель хаоса (Raccoon, 1995), которая предполагает, что фазы жизненного цикла распространяются на все уровни проекта: от всего проекта в целом до отдельной строки кода. Это означает, что проект, все его системы, модули, функции и строки кода должны быть определены, реализованы и интегрированы. Главное правило - всегда решать наиболее важную задачу первой [40].

 

2.2.3 Использование CASE-технологий при разработке.

Изменение жизненного цикла программного обеспечения стало возможным в результате использования при разработке программного обеспечения CASE-технологий.

CASE-технологии представляют собой совокупность методологий анализа, проектирования, разработки и сопровождения сложных программных систем, основанных как на структурном, так и на объектном подходах. В основу любой CASE-технологии положены методология, метод, нотация и средства [7].

 

Среди средств различают:

1)   CASE-средства анализа требований, проектирования спецификаций и структуры, редактирования интерфейсов. Первое поколение CASE-I, в основном включают средства для поддержки графических моделей, проектирования спецификаций, экранных редакторов и словарей данных;

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

Современные CASE-средства позволяют:

-   автоматизировать трудоемкие операции;

-   существенно повысить производительность труда программистов;

-   улучшить качество создаваемого программного обеспечения за счет обеспечения автоматизированного контроля совместимости спецификаций проекта;

-   уменьшить время создания прототипа системы;

-   ускорить процесс проектирования и разработки;

-   автоматизировать формирование проектной документации для всех этапов жизненного цикла в соответствии с современными стандартами;

-   частично генерировать коды программ для различных платформ разработки;

-   применять технологии повторного использования компонентов си­стемы;

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

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

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

На сегодняшний день практически все промышленно производимое сложное программное обеспечение разрабаты­вается с использованием CASE-средств.

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

 

2.3 Качество программного обеспечения

 

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

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

В настоящее время критериями качества программного обеспечения (criteria of software quality) принято считать [14]:

1) функциональность;

2) надежность;

3) легкость применения;

4) эффективность;

5)    сопровождаемость; 

6)    мобильность.

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

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

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

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

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

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

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

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

 

2.4  Роль модулей в обеспечении технологичности

 

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

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

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

Первоначально, когда размер программ был невелик, и подпро­граммы компилировались отдельно, под модулем понималась последовательность связанных фрагментов программы, обращение к которой выполняется по имени. Со временем, когда размер программ значи­тельно вырос и появилась возможность создавать библиотеки ресурсов, под модулем стали понимать автономно компилируемый набор про­граммных ресурсов. Данные модуль получает и/или возвращает через общие области памяти или параметры.

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

1) хороший модуль снаружи проще, чем внутри;

2) хороший модуль проще использовать, чем построить.

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

Принцип информационной закрытости (см. рисунок 2.8), предложенный Д. Парнасом в 1972 году, утверждает: «Содержание модулей должно быть скрыто друг от друга». Модуль должен определяться и проектироваться так, чтобы его содержимое (процедуры и данные) было недоступно тем модулям, которые не нуждаются в такой информации (клиентам).

Информационная закрытость означает следующее:

1)   все модули независимы, обмениваются только информацией, необходимой для работы;

2)   доступ к операциям и структурам данных модуля ограничен.

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

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

Рисунок 2.8 - Информационная закрытость модуля

 

Г. Майерс [23] предложил для оценки приемлемости программного модуля использовать более конструктивные его характеристики:

1) размер модуля;

2) прочность модуля;

3) сцепление с другими модулями;

4) рутинность модуля.

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

Чем выше степень независимости модулей, тем

- легче разобраться в отдельном модуле и всей программе, тестировать, отлаживать и модифицировать ее; 

- меньше вероятность появления новых ошибок при исправлении старых или внесении изменений в программу;

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

Степень независимости модулей оценивается двумя критериями: связностью (прочностью по Майерсу) и сцеплением.

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

а)         функциональная - все части модуля предназначены для выполнения одной функции;

б)        информационная (последовательная) – выходные данные одной функции слу­жат исходными данными для другой функции;

в)        коммуникативная - функции, обрабатывают одни и те же данные;

г)         процедурная - части модуля связаны порядком выполняемых ими действий, реализующих некоторый сценарий поведения;

д)        временная – части модуля не связаны, но функции выпол­няются одновременно (параллельно);

е)         логическая - базируется на объединении данных или функций в од­ну логическую группу;

ж)      случайная (по совпадению) - связь между элементами мала или отсутствует.

Анализ таблицы 2.1 показывает, что целесообразно использо­вать функциональную, информационную (последовательную) и коммуникативную связности, поскольку именно они показывают наилучшие характеристики.

 

Таблица 2.1  - Характеристика типов связности модуля

Тип связности

Сопровождаемость

Роль модуля

Функциональная

 

лучшая

 

«черный ящик»

Информационная

(последовательная)

не совсем

«черный ящик»

Коммуникативная

«серый ящик»

Процедурная

 

худшая

 

 

«белый» или «просвечивающий ящик»

Временная

«белый ящик»

Логическая

Случайная

(по совпадению)

 

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

а) сцепление по данным - модули обмениваются данными в скалярных значениях. При небольшом количестве передаваемых параметров этот тип обеспечивает наилучшие технологичес­кие характеристики ПО;

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

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

г) сцепление по внешним ссылкам - модули ссылаются на один и тот же глобальный элемент данных;

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

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

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

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

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

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

Майерс не рекомендует использовать зависящие от предыстории (непредсказуемые) модули, так как они провоцируют появление в программах «хитрых» (неуловимых) ошибок. Однако во многих случаях именно зависящий от предыстории модуль является лучшей реализаций  информационно прочного модуля.  Поэтому корректнее будет поступать согласно следующим рекомендациям [25]:

1) рутинный модуль допускается использовать, если это не приводит к плохим сцеплениям модулей;

2) зависящие от предыстории модули следует использовать только в случае, когда это необходимо для обеспечения параметрического сцепления;

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

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

В качестве средства улучшения технологических характеристик библиотек ресурсов используют разделение тела модуля на интерфейсную часть и область реализации (в Паскале –Interface и Implementation, в C++ - h и cpp-файлы).

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

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

2.5  Основные подходы к разработке программного обеспечения

 

2.5.1 Основные подходы и их особенности.

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

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

Однако этот подход имеет существенные недостатки:

- увеличивается вероятность несогласованности компонентов;

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

- интерфейс проектируется в последнюю очередь, что долго не позволяет продемонстрировать его заказчику.

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

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

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

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

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

 

Таблица 2.2 – Методы разработки при нисходящем подходе

Метод

Особенности метода

Недостатки

Иерархический

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

- большое количество достаточно слож­ных заглушек;

- основная мас­са модулей разрабатывается и реализуется в конце работы над проектом, что затрудняет распределение человеческих ресурсов.

Операционный

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

- порядок выполнения модулей может зависеть от дан­ных;

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

- при распределении человеческих ресурсов слож­ным является начало работ, пока не закончены все модули, находящиеся на так называемом критическом пути.

Комбинированный

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

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

 

Однако эти методы вызывают ряд возражений [14]: представляется сомнительным, чтобы до программирования модулей можно было разработать структуру программы достаточно точно и содержательно.

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

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

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

 

2.5.2 Парадигмы программирования.

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

Впервые  термин «парадигма программирования» применил в своих лекциях Р.Флойд - лауреат премии Тьюринга. По мнению Флойда, парадигмы программирования могут сочетаться, обогащая инструментарий программиста.

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

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

Более пятидесяти лет назад в сфере по организации вычислительных и информационных процессов получила популярность ведущая парадигма прикладного программирования на основе императивного управления и процедурно-операторного стиля построения программ.

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

1)   императивные (imperative), называемые также процедурными (procedural) или директивными (directive);

2)   декларативные (declarative);

3)   объектно-ориентированные (object-oriented).

Императивное программирование - это парадигма программирования, которая описывает процесс вычисления в виде инструкций, изменяющих состояние программы [28]. Императивная программа очень похожа на приказы, то есть это - последовательность команд, которые должен выполнить компьютер. Первыми императивными языками были машинные коды, инструкции которых были крайне просты, что снижало нагрузку на компьютеры, однако затрудняло написание крупных программ. В 1954 появился первый «человеческий» язык программирования, максимально приближенный к естественному, — FORTRAN (Дж. Бэкус, IBM), который является компилируемым и позволяет использовать именованные переменные, составные выражения, подпрограммы и многие другие элементы распространённых сейчас императивных языков. С тех пор семейство императивных языков пополнили:

- ALGOL (конец 1950-х), разработанный с целью упростить выражение математических алгоритмов и в дальнейшем послуживший базой для написания операционных систем для некоторых моделей компьютеров;

- COBOL (1960) и BASIC (1964), появившиеся в результате попыток сделать программирование более похожим на обычный английский язык;

- а также Pascal, (Н.Вирт, начало 1970-х), C (Д. Ритчи), Ada (Honeywell, 1978), С++ (Б.Страуструп, 1985), Perl (Л.Уолл, 1987), Python (Гвидо ван Россум, 1990), PHP (Р.Лердорф, 1994), Java (Sun Microsystems, 1994), C# (1998).

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

Теоретическое (доказательное) программирование - технология разработки программ с доказательствами правильности - доказательствами отсутствия ошибок в программах (несоответствий между программой и реализуемым ею алгоритмом), использовавшаяся в 1980-х годах в академических кругах. Программирование пытается выразить свои формальные модели, показать их значимость и фундаментальность. Эти модели унаследовали основные черты родственных математических понятий и утвердились как алгоритмический подход в информатике [13].

Стремление к доказательности построений и оценка их эффективности, правдоподобия, правильности, корректности и других формализуемых отношений на схемах и текстах программ послужили основой структурного программирования [37] и других методик достижения надежности процесса разработки программ, например, литературное (грамотное) программирование. Стандартные подмножества Алгола и Паскаля, послужившие рабочим материалом для теории программирования, сменились более удобными для экспериментирования аппликативными языками такими, как ML, Miranda, Scheme и другие диалекты Lisp. В настоящее время к ним присоединяются подмножества C и Java.

Структурное программирование (или программирование без goto) - методология разработки программного обеспечения, в основе которой лежит представление программы в виде иерархической структуры блоков. Предложена в 70-х годах XX века Э. Дейкстрой, разработана и дополнена Н. Виртом. Методология структурной разработки программного обеспечения была признана «самой сильной формализацией 1970-х годов». Является одним из способов обеспечения высокого уровня технологичности разрабатываемого программного обеспечения. Различают три вида вычислительного процесса, реализуемого программами: линейный, разветвленный и циклический.

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

Декларативное (логическое) программирование - парадигма программирования, основанная на теории и аппарате математической логики [38]. Возникло как упрощение функционального программирования для математиков и лингвистов, решающих задачи символьной обработки.

Программа «декларативна», если она описывает, что представляет собой нечто, а не как его создать. Например, веб-страницы на HTML декларативны, так как они описывают, что именно должна содержать страница, а не как ее отображать на экране. Декларативные программы пишутся на исключительно функциональном, логическом языках или языке программирования с ограничениями. Самым известным языком логического программирования является Prolog. Примеры использования подобных технологий можно увидеть в Microsoft ASP.NET и Microsoft Windows Communication Foundation.

Функциональное программирование - в основу функциональной парадигмы и функционального стиля программирования положен простой принцип: функция — вполне подходящее и адекватное средство описания вычислений [36]. Функциональная программа представляет собой набор определений функций. Функции определяются через другие функции или рекурсивно через самих себя. При выполнении программы функции получают параметры, вычисляют и возвращают результат, при необходимости вычисляя значения других функций. На функциональном языке программист не должен описывать порядок вычислений. Нужно просто описать желаемый результат как систему функций [35].

Функциональное программирование нашло большое применение в теории искусственного интеллекта и её приложениях.

Продуманность и методическая обоснованность первых реализаций основного языка функционального программирования Lisp (List processor) позволила быстро накопить опыт решения новых задач, подготовить их для прикладного и теоретического программирования. В настоящее время существуют сотни функциональных языков программирования, ориентированных на разные классы задач и виды технических средств, в том числе язык-прототип ISWIM, Scheme, ML, Caml, Miranda, Haskell, Clean – диалекты Lisp [24].

Развитием функциональной парадигмы стало аппликативное программирование [36]. Аппликативный подход к написанию программы состоит в систематическом осуществлении применения одного объекта к другому. Результатом такого применения вновь является объект, который может участвовать в применениях как в роли функции, так и в роли аргумента и т. д. Это делает запись программы математически ясной. Конструкции аппликативных языков программирования, в целом отличает простота исходных посылок. Их базовыми строительными блоками являются представления о выражении и функции, а все прочие понятия являются производными и вводятся шаг за шагом, что придаёт конструктивный стиль самому процессу программирования.

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

- низкоуровневое (машинно-ориентированное) программирование;

- системное программирование;

- декларативно-логическое программирование;

- оптимизационно-трансформационное программирование;

- высокопроизводительное (параллельное) программирование.

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

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

При построении трансляторов используется автоматное программирование - это парадигма программирования, при использовании которой программа или её фрагмент осмысливается как модель какого-либо формального автомата. В зависимости от конкретной задачи в автоматном программировании могут использоваться как конечные автоматы, так и автоматы более сложной структуры. Автоматное программирование [26] широко применяется при построении лексических анализаторов (классические конечные автоматы) и синтаксических анализаторов (автоматы с магазинной памятью). К языкам автоматного программирования относятся:

- язык последовательных функциональных схем SFC (Sequential Function Chart) - графический язык программирования широко используется для программирования промышленных логических контроллеров PLC;

- дракон-схемы - графический язык программирования, используется для программирования в ракетно-космической технике;

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

Оптимизационно-трансформационное программирование объединило технику оптимизации программ, макрогенерации и частичных вычислений. Парадигма базируется на эквивалентности информации, которая проявляется в определении преобразований программ и процессов, в поиске критериев применимости преобразований, в выборе стратегии их использования [36]. В качестве методов повышения эффективности информационной обработки использует смешанные вычисления, отложенные действия, «ленивое» программирование, задержанные процессы и т.п.

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

В том или ином виде разными языками программирования поддерживается обобщённое программирование - парадигма программирования, заключающаяся в таком описании данных и алгоритмов, которое можно применять к различным типам данных, не меняя само это описание. Возможности обобщённого программирования впервые появились в 1970-х годах в языках Клу и Ада, а затем во многих объектно-ориентированных языках таких, как C++, Java, Object Pascal, D, Eiffel, языках для платформы .NET и других.

В результате эволюции объектно-ориентированной парадигмы  программирования (см. п.1.2.3)  появились:

- аспектно-ориентированное программирование (АОП) - парадигма программирования, основанная на идее разделения функциональности для улучшения разбиения программы на модули [24]. Методология была предложена группой инженеров исследовательского центра Xerox PARC под руководством Грегора Кичалеса (Gregor Kiczales). В 2001 г. ими же было разработано аспектно-ориентированное расширение для языка Java, получившее название AspectJ. AOП дополняет объектно-ориентированное программирование, обогащая его другим типом модульности – аспектами. Аспекты в системе могут изменяться, вставляться, удаляться на этапе компиляции и, более того, повторно использоваться;

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

- компонентно-ориентированное программирование - парадигма программирования, ключевой фигурой которой является компонент - независимый модуль программного кода, предназначенный для повторного использования и развертывания [24]. Компонентно-ориентированное программирование включает в себя набор ограничений, налагаемых на механизм объектно-ориентированного программирования. Среди языков компонентно-ориентированного программирования можно выделить Оберон (1987, Н.Вирт), компонентный Паскаль, PHP.

- прототипное программирование - стиль объектно-ориентированного программирования, при котором отсутствует понятие класса, а повторное использование (наследование) производится путём клонирования существующего экземпляра объекта (прототипа). Примером прототип-ориентированного языка является язык Self. В дальнейшем этот стиль программирования начал обретать популярность и был положен в основу таких языков программирования, как JavaScript, Lua, Io, REBOL [17].

 

2.5.3 Способы описания вычислительных процессов.

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

Для изображения схем алгоритмов каждой группе дейст­вий ставится в соответствие специальный блок. Стан­дарт [10] предусматривает блоки для обозначения циклов, не запрещает произвольной передачи управления и допускает использование команд услов­ной и безусловной передачи управления при реализации алгоритма.

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

К базовым относят:

а)     следование - обозначает последовательное выполнение действий;

б)    ветвление -  выбор одного из двух вариантов действий;

в)    цикл-пока - определяет повторение действий, пока не будет нарушено некоторое условие, выполнение которого проверяется в начале цикла.

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

а)     выбор - выбор одного варианта из нескольких в зависимости от значения некоторой величины;

б)    цикл-до - повторение действий до выполнения заданного условия, проверка которого осуществляется после выполнения действий в цикле;

в)    цикл с заданным числом повторений (счетный цикл) - повторение некоторых действий указанное количество раз.

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

Пример 2.1 – Использование блок-схемы для описания алгоритма поиска в массиве А(n) элемента, равного заданному (см. рисунок 2.9).

Рисунок 2.9 – Фрагмент блок-схемы алгоритма поиска

В приведенном примере используется структурный вариант алгоритма (цикл-пока). Элементы массива перебираются и поочередно сравниваются с заданным значением Y. В результате выводится соответствующее сообщение.

К недостаткам блок-схем можно отнести следующие:

а)     низкий уровень детализации, что скрыва­ет суть сложных алгоритмов;

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

Кроме схем, для описания алгоритмов можно использовать псевдокоды, Flow-формы и диаграммы Насси-Шнейдермана, которые базируются на тех же основных структурах, допускают разные уровни детализации и делают невозможным описание неструктурных алгоритмов.

Таблица  2.3 – Соответствие различных способов описания алгоритмов

Структура

Псевдокоды

Flow-формы

Диаграммы

Насси-Шнейдермана

Следование

<действие 1>

<действие 2>

Ветвление

   Если <условие>

      то <действие 1>

      иначе <действие 2>

   Все-если

Цикл-пока

   Цикл-пока <условие>

<действие>

   Все-цикл  

Выбор

   Выбор <код>

   <код 1>: <действие 1>

   <код 2>: <действие 2>

    иначе <действие 3>

   Все-выбор

Цикл с парамет-ром

   Для <индекс> = 

        <n>,<m>,<h>

        <действие >

   Все-цикл

Цикл-до

   Выполнять

<действие>

   До <условие>

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

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

Пример 2.2 – Использование псевдокода для описания алгоритма поиска в массиве А(n) элемента, равного заданному (фрагмент).

i :=1

Цикл-пока  i £ n и A(i) ¹ Y

i := i + 1

Все-цикл

Если i £ n

          то Вывести «Элемент найден»

      иначе Вывести «Элемент не найден»

Все-если

 

Flow-формы - графическая нотация описания структурных алгоритмов, иллюстрирующая вложенность структур.

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

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

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

Пример 2.3 – Использование Flow-форм для описания алгоритма поиска в массиве А(n) элемента, равного заданному (см. рисунок 2.10).

Рисунок 2.10 –  Flow-форма алгоритма поиска (фрагмент)

 

Пример 2.4 – Использование диаграмм Насси-Шнейдермана для описания алгоритма поиска в массиве А(n) элемента, равного заданному (см. рисунок 2.11).

Рисунок 2.11 –  Фрагмент диаграммы Насси-Шнейдермана

 

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

Общим недостатком Flow-форм и диаграмм Насси-Шнейдермана являет­ся сложность построения изображений символов, что усложняет практическое применение этих нотаций для описания больших алгоритмов.

 

2.6 Стили оформления программы

 

Исходя из того, что любой модуль программы, написанной при реализации проекта, неоднократно придется просматривать, следует придерживаться хорошего стиля написания программ. С точки зрения технологичности хорошим считают стиль оформления программы, облегчающий ее восприятие как самим автором, так и другими программистами, которым придется ее проверять или модифицировать. «Помните, программы читаются людьми» - призывал Д. Ван Тассел, автор одной из известных монографий [5], посвященной проблемам программирования. Стиль оформления программы включает:

а) правила именования объектов (переменных, функций, типов и т. п.);

б) правила оформления модулей;

в) стиль оформления текстов модулей.

 

2.6.1 Имена объектов программы.

При выборе имен программных объектов следует придерживаться следующих правил:

а) имя объекта должно соответствовать его содержанию, например:

Maxltem - максимальный элемент; Nextltem - следующий элемент;

б) если позволяет язык программирования, можно использовать символ «_» для визуального разделения имен, состоящих из нескольких слов, напри­мер: Max_Item, Next_Item;

в) необходимо избегать близких по написанию имен, например: Index и InDec.

Кроме того, полезно использовать осмысленные имена для глобальных переменных и короткие имена — для локальных [42].

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

Для локальных переменных, наоборот, лучше подходят короткие имена. Обычно используемые локальные переменные по соглашению могут иметь очень короткие имена.

Так, употребление i и j для обозначения счетчиков цикла, р и q для указателей, s и t для строк стало настолько привычным, что применение более длинных имен не принесет никакой пользы, а наоборот, может даже навредить.

Существует множество соглашений и традиций именования. К наиболее распространенным правилам относятся:

- использование для указателей имен, начинающихся или заканчивающихся на р (от pointer, указатель);

- заглавных букв в начале имен глобальных переменных (например, Row, Col) и всех заглавных — в именах констант (например, ROW, COL);

- отображение в имени переменной информации об ее типе и способе использования (например, strTo — строки вывода);

- имя функции должно базироваться на активном глаголе, за которым может следовать существительное (например, getTime).

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

Чем больше размер кода, тем важнее использовать информативные и систематизированные имена.

 

2.6.2 Правила оформления модулей.

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

а)   название модуля;

б)   краткое описание его назначения;

в)   краткое описание входных и выходных параметров с указанием единиц измерения;

г)   список используемых (вызываемых) модулей;

д)   краткое описание алгоритма (метода) и/или ограничений;

е)   ФИО автора программы;

ж)  идентифицирующую информацию (номер версии и/или дату последней корректировки).

 

 

 

Пример 2.5 – Оформление модуля программы (см. рисунок 2.12).

Рисунок 2.12 – Оформление модуля программы

 

2.6.3 Стиль оформления текстов модулей.

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

Пример 2.6 – Использование комментариев в С++

void main ()

{

// инициализация переменных

// вычисление выражения

cout<<”Result=”<<y;

// операция над результирующей переменной

cout<<”Result operation”<<y;

}

Для таких языков, как Pascal, C++ и Java использование отступов позволяет прояснить структуру программы: обычно дополнительный отступ обозначает вложение операторов языка.

Пример 2.7 – Использование дополнительных отступов в С++

void main ()

{                                                        // начало функции

   int k, y;

      for (k=1;k<=10;k++)

         {                                                // начало тела цикла        

if (y*y-5>60)   break;                

         cout<<y*y-5<<endl;                        

     }                                                 // конец тела цикла

}                                                         // конец функции

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

Пример 2.8 – Использование комментариев с неочевидной информацией

// проверка условия и выход, если условие не выполняется

if (y*y-5>60)  

    {

cout<<”Значение не попадает в указанный диапазон”<<endl;

break;     

                    }      

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

 

         2.7 Программирование без ошибок

 

2.7.1 Классификация ошибок программирования.

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

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

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

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

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

а)    ошибки передачи - аппаратные средства искажают данные;

Рисунок 2.13 – Способы проявления ошибок

 

б)   ошибки преобразования - программа неверно преобразует исходные данные из входного формата во внутренний;

в)   ошибки перезаписи - пользователь ошибается при вводе данных;

ошибки данных — пользователь вводит неверные данные.

 

2.7.2 Способы устранения ошибок.

Ошибки передачи обычно контролируются аппаратно.

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

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

Неверные данные обычно может обнаружить только пользователь.

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

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

Для снижения погрешности результатов вычислений следует:

а)     избегать вычитания близких чисел (машинный ноль);

б)    избегать деления больших чисел на малые;

в)    сложение длинной последовательности чисел начинать с меньших по абсолютной величине;

г)     стремиться по возможности уменьшать количество операций;

д)    использовать методы с известными оценками погрешностей;

е)     не использовать условие равенства вещественных чисел;

ж)  вычислять с двойной точностью, а результат выдавать - с одинарной.

Поскольку полный контроль данных на входе и в процессе вычислений невозможен, следует предусматри­вать перехват и обработку аварийных ситуаций. Для перехвата и обработки аппаратно и программно фиксируемых ошибок в некоторых языках программирования (Delphi Pascal, C++ и Java) предусмотрены средства обработки исключений. Использование этих средств позволяет не допустить выдачи пользователю сообщения об аварий­ном завершении программы, а программист получает возможность предусмотреть действия, позволяющие исправить эту ошибку или выдать пользователю сооб­щение с точным описанием ситуации и продолжить работу.

 

2.7.3. Контроль структуры программы.

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

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

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

Сквозной контроль - это проверка структуры программы при выполнении заранее разработанных тестов.

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

 

3 глава. Требования и исходные данные к разработке программного обеспечения

 

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

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

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

 

­3.1 Классификация программного обеспечения по функциональному признаку

 

Каждый программный продукт предназначен для выполнения опреде­ленных функций. По функциональному признаку все программные продукты можно разде­лить на три группы [32]: системные, прикладные и гибридные (см. рисунок 3.1).

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

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

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

Рисунок 3.1 – Классификация программных продуктов по их назначению

 

Современные среды программирования (Delphi, Visual C++) реализуют визуальную технологию разработки программных продуктов и предоставляют программистам огромные библиотеки компо­нентов. К этой же группе отно­сят инструментальные комплексы создания баз данных (Access, FoxPro, Oracle), средства создания интеллектуальных систем (экспертных, обучающих, систем контроля знаний). Последнее достижение в этом направлении - CASE-средства разработки программного обеспече­ния (ERwin, BPwin, Paradigm Plus, Rational Rose и другие).

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

а)     продукты общего назначения:

- текстовые редакторы;

- элек­тронные таблицы;

- графические редакторы;

- информационные си­стемы общего назначения;

- программы-переводчи­ки;

б)    профессиональные среды:

- системы автоматизации проектирования;

- системы-тренажеры;

- бухгалтерские системы;

- издательские системы;

- профессиональные графические системы; 

- экспертные системы;

в)    обучающие системы;

г)     развлекающие программы:

- информационные системы с тестами развлекающего харак­тера;

- музыкальные программы;

- игровые программы.

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

 

3.2 Эксплуатационные требования к программному обеспечению

 

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

а)     правильность - функционирование в соответствии с техническим за­данием;

б)    универсальность - обеспечение правильной работы при любых допу­стимых данных и защиты от неправильных данных;

в)    надежность (помехозащищенность) - обеспечение полной повторяе­мости результатов (правильности при наличии различ­ного рода сбоев);

г)     проверяемость - возможность проверки получаемых результатов;

д)    точность - обеспечение погрешности результатов не выше заданной;

е)     защищенность - обеспечение конфиденциальности информации;

ж)  программная совместимость - возможность совместного функциони­рования с другим программным обеспечением;

з)     аппаратная совместимость - возможность совместного функциони-ро­вания с некоторым оборудованием (указывается минимально возможная конфигурация оборудования, на котором будет работать ПО);

и)    эффективность - использование минимально возможного количества ресурсов технических средств (время ответа системы, объем оперативной и внешней памяти, количество обслуживаемых внешних устройств);

к)    адаптируемость - возможность быстрой модификации с целью при­способления к изменяющимся условиям функционирования;

л)    повторная входимость - возможность повторного выполнения без пе­резагрузки с диска;

м)   реентерабельность - возможность «параллельного» использования не­сколькими процессами (все данные, изменяемые программой в процессе выполнения, должны быть выделены в специальный блок, копия которого создается для каждого процесса при вызове программы).

 

3.3  Постановка задачи

 

3.3.1 Предпроектные исследования.

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

Существуют два варианта неопределенности:

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

б)    неизвестна структура автоматизируемых информационных процессов - обычно встречается при построении автоматизированных систем управле­ния предприятиями, поэтому в этом случае определяют:

1)            структуру и взаимосвязи информационных процес­сов;

2)            распределение функций между человеком и системой, аппаратурой и программным обеспечением;

3)            функции программного обеспечения, условия его функцио­нирования, особенности аппаратных и пользовательских интерфейсов;

4)            требования к программным и информационным компонентам, необхо­димые аппаратные ресурсы, требования к базам данных и физические харак­теристики программных компонент.

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

 

3.3.2 Разработка технического задания.

Результаты предпроектных исследований предметной области использу­ются в процессе разработки технического задания.

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

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

а)     исходные данные и требуемые результаты, определяющие функ­ции программы или системы;

б)    среда функционирования (программная и аппаратная) - за­дается или выбирается для обеспечения параметров, указанных в техни­ческом задании;

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

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

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

2) определяют перечень результатов, их характеристики и способы представления;

3) уточ­няют среду функционирования программного обеспечения: конкретную ком­плектацию и параметры технических средств, версию используемой опера­ционной системы, версии и параметры другого установленного программного обеспечения, с которым предстоит взаимодействовать буду­щему программному продукту;

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

На техническое задание при разработке программного обеспечения существует стандарт ГОСТ 19.201-78 «Техни­ческое задание. Требования к содержанию и оформлению». В соответствии с этим стандартом техническое задание должно содержать следующие раз­делы:

1)     Введение - демонстрирует актуальность разработки и показывает, какое место эта разработка занимает в ряду подобных; включает наименование и краткую характеристику об­ласти применения программы или программного продукта, а также объекта, в котором предполагается их использовать;

2)     Основания для разработки - содержит наименование до­кумента, на основании которого ведется разработка, организации, утвердив­шей данный документ, и наименование или условное обозначение темы раз­работки (например, документом может служить план, приказ, договор и т.п.);

3)     Назначение разработки - содержит описание функцио­нального и эксплуатационного назначения программного продукта с указа­нием категорий пользователей;

4)     Требования к программе или программному изделию включает подразделы:

- Требования к функциональным характеристикам, в котором перечислены выполняемые функции, описаны состав, характеристики и фор­мы представления исходных данных и результатов; при не­обходимости указывают критерии эффективности (максимально допустимое время ответа системы, максимальный объем используемой оперативной и/или внешней памяти и др.);

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

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

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

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

- Требования к маркировке и упаковке;

- Требования к транспортированию и хранению;

- Специальные требования;

5)   Требования к программной документации – содержит перечень  необходимой сопроводительной документации (руководство программиста, руководство пользователя, ру­ководство системного программиста, пояснительная записка и т. п.);

6)   Технико-экономические показатели – содержит сведения об ориентировочной экономической эффективности, предполагаемой годовой потребности и экономических преимуществах по сравнению с существующими аналогами;

7)   Стадии и этапы разработки – содержит перечень стадий разработки и этапов, а также содержание работ с указанием сроков разработки и исполнителей;

8)   Порядок контроля и приемки -  содержит перечень видов испытаний и общие требования к приемке работы.

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

В зависимости от особенностей разрабатываемого продукта разрешает­ся использовать подразделы, вводить но­вые разделы или объединять их.

Если какие-либо требования, предусмотренные техническим заданием, заказчик не предъявляет, следует в соответствующем месте ука­зать «Требования не предъявляются».

Образец выполнения технического задания на создание системы «Учет успеваемости студентов» и пример оформления титульного листа приведены в Приложении А.

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

 

3.3.3 Принятие принципиальных решений.

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

- выбор архитектуры программного обеспечения;

- типа пользовательского интерфейса;

- технологии работы с до­кументами;

- выбор подхода к разработке;

- выбор языка и среды программирования.

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

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

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

В рамках однопользовательской архитектуры различают:

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

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

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

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

Многопользовательскую архитектуру реализуют системы, построенные по принципу «клиент-сервер». Многопользовательские программные системы должны организовывать сетевое взаимодействие от­дельных компонентов ПО, что усложняет про­цесс его разработки, поэтому для разработки используют специальные технологии или платформы (технологии CORBA, COM, Java).

Тип пользовательского интерфейса во многом определяет сложность и трудоемкость разработки. По последним данным до 80 % программного кода может реализовывать именно пользовательский интерфейс [22]. Различают четыре типа пользовательских интерфейсов:

а)     примитивные - реализуют единственный сценарий работы, используя операции  ввода данных, их обработки и вывода результатов;

б)    меню - реализуют множество сценариев работы, операции которых ор­ганизованы в иерархические структуры;

в)    со свободной навигацией - реализуют множество сценариев, операции которых не привязаны к уровням иерархии, и предполагают определение множества возможных операций на конкретном шаге работы; интерфейсы данной формы в основном используют Windows-приложения;

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

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

Выбор типа интерфейса включает выбор технологии рабо­ты с документами. Различают две основные технологии:

а)     однодокументная, которая предполагает однодокументный интерфейс (SDI - Single Document Interface) и используется, если одновременная работа с несколькими документами не обя­зательна;

б)    многодокументная, которая предполагает многодокументный интер­фейс (MDI - Multiple Document Interface) и используется, если программное обеспе­чение должно работать с несколькими документами одновременно, напри­мер, с несколькими текстами или несколькими изображениями.

Трудоемкость реализации многодокументных интерфейсов с использо­ванием современных библиотек примерно на 3...5 % выше, чем однодокументных, однако тип влияет на трудоемкость более существенно.

При выборе интерфейса прямого манипулирования или со свободной на­вигацией практически однозначно предполагается использование объектного подхода и событийного програм­мирования, так как современные среды визуального программирования, такие как Visual C++, Delphi, Builder C++, предоставляют интерфейсные компоненты именно в виде объектов библио­течных классов. При этом в зависимости от сложности предметной области программное обеспечение может реализовываться как с использованием объектов и, соответственно, классов, так и чисто процедурно. Исключение составляют случаи использования специализированных языков разработки Интернет-приложений (Perl), построенных по совершенно другому принципу.

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

Объектный подход эффективен для разработки очень больших программных систем (более 100000 операторов) и в случаях, когда объектная структура предметной области ярко выражена. Следует осторожно использовать объ­ектный подход при жестких ограничениях на эффективность программного обеспечения, например, при разработке систем реально­го времени. Во всех прочих случаях выбор подхода остается за разработчиком.

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

- организацией, ведущей разработку;

- программистом, который по возможности всегда будет использовать хорошо знакомый язык;

- устоявшимся мнением.

В общем случае все существующие языки программирования модно разделить на четыре группы [1]:

а)     универсальные языки высокого уровня;

б)    специализированные языки разработчика программного обеспечения;

в)    специализированные языки пользователя;

г)     языки низкого уровня.

В группе универсальных языков высокого уровня безусловным лидером сегодня является язык С (вместе с C++). Действи­тельно различные версии С и C++ имеют целый ряд очень существенных до­стоинств [3]:

а)     многоплатформенность - для всех используемых в настоящее время платформ существуют компиляторы с языка С и C++;

б)    наличие операторов, реализующих основные структурные алгоритми­ческие конструкции (условную обработку, все виды циклов);

в)    возможность программирования на низком (системном) уровне с ис­пользованием адресов оперативной памяти;

г)     огромные библиотеки подпрограмм и классов.

Все это сделало С и C++ основными языками, используемыми для со­здания операционных систем, и, в свою очередь, служит для них дополни­тельной рекламой. Однако они имеют и серьезные недостатки:

а)     отсутствие полноценных встроенных структурных типов данных;

б)    наличие синтаксических неоднозначностей, которые также не позволя­ют компилятору контролировать правильность программы;

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

Альтернативой С и C++ среди универсальных языков программирова­ния, используемых для создания прикладного программного обеспечения, на сегодня является Pascal, компиляторы которого в силу четкого синтаксиса об­наруживают помимо синтаксических и большое количество семантических ошибок. Версия Object Pascal, использованная в среде Delphi, сопровождает­ся профессиональными библиотеками классов, упрощающими ведение боль­ших разработок, в том числе и требующих использования баз данных, что де­лает Delphi достаточно эффективной средой для создания приложений Win­dows.

Кроме этих языков, к группе универсальных принадлежат также Basic, Modula, Ada и некоторые другие. Каждый из указанных языков так же, как C++ и Pascal, имеет свои особенности и, соответственно, свою область приме­нения.

Специализированные языки разработчика исполь­зуют для создания конкретных типов программного обеспечения. К ним от­носят:

а)     языки баз данных;

б)    языки создания сетевых приложений;

в)    языки создания систем искусственного интеллекта и т. д.

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

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

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

а)     при написании сравнительно простых программ, взаимодействующих непосредственно с техническими средствами (например, драйверов);

б)    в виде вставок в программы на языках высокого уровня.

Таким образом, при выборе языка программирования следует руководствоваться следующими соображениями:

а)     язык должен быть удобен для программиста;

б)    язык должен быть пригоден для данного компьютера;

в)    язык должен быть пригоден для решения данной задачи.

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

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

Наиболее часто используют визуальные среды Delphi, C++ Builder фирмы Borland (Inprise Corporation), Visual C++, Visual Basic фирмы Microsoft, Visual Ada фирмы IBM.

Причем, среды фирмы Microsoft обеспечивают более низкий уровень программирования «под Windows». Это является их достоинством (уменьшается вероятность возникновения «нестандартной» ситуации) и недостатком (существенно загружает программиста «рутинной» работой, от которой избавлен программист, работающий с Delphi или C++ Builder).

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

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

 

3.4 Анализ требований и определение спецификаций

 

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

Спецификации – это полное и точное описание функций и ограничений разрабатываемого программного обеспечения. Различают:

- функциональные спецификации, которые описывают функции разрабатываемого программного продукта и состав обрабатываемых данных;

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

Естественный язык для описания спецификаций не подходит, поскольку не обеспечивает необходимой точности.

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

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

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

- спецификации процессов;

- словарь терминов;

- диаграммы переходов состояний;

- функциональные диаграммы;

- диаграммы потоков данных.

Спецификации процессов обычно представляют в виде краткого текстового описания, схем алгоритмов, псевдокодов, Flow-форм или диаграмм Насси-Шнейдермана. Для краткости и понятности описания не только разработчику, но и заказчику, чаще всего используют псевдокоды.

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

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

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

Рисунок 3.2 - Пример диаграммы переходов состояний программного обеспечения, не взаимодействующего с окружающей средой

 

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

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

Рисунок 3.3 - Пример диаграммы переходов состояний программного обеспечения, активно взаимодействующего с окружающей средой

 

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

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

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

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

Рисунок 3.4 – Функциональный блок и интерфейсные дуги

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

Блоки и дуги сопровождаются текстами на естественном языке.

Блоки на диаграмме размещают по «ступенчатой» схеме в соответствии с последовательностью их работы или доминированием - влиянием, которое оказывает один блок на другие.

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

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

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

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

- внешняя сущность -  объект или физической лицо, которое является источником или приемником информации (банк, персонал, клиент и т.д.);

- процесс – преобразование входных данных в выходные в соответствии с алгоритмом;

- хранили­ще (накопителя) данных – абстрактное устройство для хранения информации (картотека, база данных, файл и т.д.);

- поток данных – процесс передачи информации от источника к приемнику (автоматически ил вручную).

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

Рисунок 3.5 – Классификация структур данных

Различают:

- абстрактные структуры данных, используемые для уточне­ния связей между элементами;

- конкретные структуры, используемые для представления данных в программах.

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

а)     анализ условия задачи;

б)    выбор математических абстракций, адекватно (с требуемой точ­ностью и полнотой) представляющих исходные данные и результаты;

в)    формальную постановку задачи;

г)     определение метода преобразования исходных данных в результат (метода решения задачи).

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

При выборе метода учитывают:

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

- требования к результатам (допустимую погрешность);

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

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

 

4 глава. Особенности проектирования программного обеспечения при различных подходах

 

4.1 Структурный подход

 

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

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

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

Структурными компонентами программной системы/комплекса служат программы, библиоте­ки ресурсов, подсистемы, базы данных. Структурная схема программного комплекса демонстри­рует передачу управления от программы-диспетчера соответствующей про­грамме (см. рисунок 4.1а).

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

С точки зрения взаимодействия его компонентов между собой и с внеш­ней более полное представление о проектируемом программном обеспечении средой дает функциональная схема. Функциональная схема (схема данных, ГОСТ 19.701-90) - схема взаимодействия компонентов программного обеспечения с описанием информационных потоков, состава данных в потоках и указанием используемых файлов и устройств.

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

Рисунок 4.1 - Пример структурной и функциональной схем программного комплекса

    

Рисунок 4.2  – Пример структурной и функциональной схем программной системы

Для изображения функцио­нальных схем используют специальные обозначения, установленные стан­дартом. Основные обозначения схем данных приведены в таблице 4.1.

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

Таблица  4.1 – Основные обозначения схем данных

Название блока

Обозначение

Назначение блока

Запоминаемые данные

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

Оперативное запоминающее устройство

Для обозначения таблиц и других структур данных, хранящихся в оперативной памяти

Запоминающее устройство с последовательной выборкой

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

Запоминающее устройство с прямым доступом

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

Документ

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

Ручной ввод

Для обозначения ручного ввода данных с клавиатуры

Карта

Для обозначения данных на магнитных или перфорированных картах

Дисплей

Для обозначения данных, выводимых на дисплей

 

Разбиение на модули выполняется эв­ристически, исходя из рекомендуемых размеров модулей (20-60 строк) и сложности структуры (2-3 вложенных управляющих конструкции). Для анализа технологичности иерархии модулей используют методики Константайна или Джексона [32].

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

Методика Джексона основана на поиске соответствий структур исходных данных и результатов. Однако при ее применении возможны ситуации, когда на ка­ких-то уровнях соответствия отсутствуют. Например, записи исходного фай­ла сортированы не в том порядке, в котором соответствующие строки долж­ны появляться в отчете. Такие ситуации были названы «столкновениями».

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

 

4.2 Объектный подход

 

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

Когда в середине 80-х годов ХХ века для разработки программного обеспечения большого объема было предложено использовать объектный подход, в качестве основной технологии выбрано объектно-ориентированное программирование (ООП) - методика разработки программ, в основе которой лежит понятие объекта [18].

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

Объекты, описываемые одинаковыми наборами атрибутов, объединяются в классы. Данные класса называются полями, процедуры и функции — методами.

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

Поскольку объект - это динамическая структура, переменная-объект содержит не данные, а ссылку на данные объекта. Поэтому программист должен позаботиться о выделении памяти для этих данных. Выделение памяти при создании объекта осуществляется при помощи специального метода класса – конструктора (constructor),  а освобождение памяти при его уничтожении - при помощи деструктора (destructor).

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

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

а)     уменьшение сложности программного обеспечения;

б)    повышение надежности программного обеспечения;

в)    обеспечение возможности модификации отдельных компонентов программного обеспечения без изменения остальных его компонентов;

г)     обеспечение возможности повторного использования отдельных компонентов программного обеспечения.

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

На заре эпохи ООП были предложены методы анализа и проектирования в рамках объектного подхода, использующие раз­личные модели и нотации. Спорить о достоинствах и недостатках этих методов и моделей можно было бесконечно. Эта ситуация получила название «войны методов». Конец «войне методов» положило появление в 1995 г. первой версии языка UML (Unified Modeling Language - унифицированный язык моделиро­вания), который был создан ведущими специалистами в этой области (Гради Бучем, Иваром Якобсоном и Джеймсом Рамбо) и в настоящее время фактически признан стандартным средством описания проектов, создаваемых с использованием объектно-ориентированного подхода [2, 33, 34].

UML объединил лучшие современные технические приемы моделирования и разработки программного обеспечения. По сути, язык UML был задуман так, чтобы его можно было реализовать посредством его же инструментальных средств. Фактически это признание того, что большие современные программные системы, как правило, нуждаются в инструментальной поддержке. UML-диаграммы легко воспринимаются и при этом без труда генерируются компьютерами. UML объединил лучшие идеи «доисторических» методов, отказываясь от их наиболее специфических деталей.

Спецификация разрабатываемого программного обеспечения при ис­пользовании UML объединяет несколько моделей [6]: использования, логичес­кую, реализации, процессов и развертывания (см. рисунок 4.3).

Рисунок 4.3 - Полная спецификация разрабатываемого программного обеспечения при объектном подходе (UML)

Логическая модель описывает ключевые абстракции ПО (классы, интерфейсы), т. е. средства, обеспечивающие требуемую функциональность.

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

Модель использования представляет собой описание функциональности программного продукта с точки зрения пользователя.

Модель процессов отображает организацию вычислений и оперирует по­нятиями «процессы» и «нити». Она позволяет оценить производительность, масштабируемость и надежность программного обеспечения.

Модель развертывания показывает особенности размещения программных компонентов на конкретном оборудовании.

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

В процессе анализа требований необходимо понять, что именно ожидают от системы пользователи программного обеспечения. Для этого в распоряжении имеется множество приемов UML. В общей сложности UML2 предлагает тринадцать дополняющих друг друга диаграмм [2, 34], вхо­дящих в различные модели (см. рисунок 4.4). Все диаграммы используют единую графическую нотацию, что существенно облегчает их понимание.

В общем случае можно выделить два вида диаграмм UML: диаграмма структуры и  диаграмма поведения.

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

В состав диаграммы структуры входят шесть диаграмм:

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

Рисунок 4.4 – Классификация диаграмм UML

2) диаграмма пакетов демонстрирует взаимосвязи набо­ров классов, объединенных в пакеты (логические блоки системы, представляющие группы времени компиляции), между собой и помогает держать их под контролем. Фактически - это хорошая логическая маршрутная карта системы. Диаграммы пакетов исключительно удобны в больших по размерам системах для представления картины зависимостей между основными элементами системы;

3) диаграмма объектов - это снимок объектов системы в какой-то момент времени. Поскольку она показывает экземпляры, а не классы, то диаграмму объектов часто называют диаграммой экземпляров. Диаграмму объектов можно использовать для отображения одного из вариантов конфигурации объектов;

4) диаграмма компонентов показывает, из каких программных компонентов (элементов, которые можно независимо друг от друга купить и обновить) состоит программное обеспечение и как эти ком­поненты связаны между собой;

5) диаграмма развертывания (или диаграмма размещения) отражает физическое расположение системы, показывая, на каком физическом оборудовании запускается та или иная составляющая программного обеспечения;

6) диаграмма составных структур – новый вид диаграмм, появившийся в языке UML2. Одной из наиболее значимых новых черт языка UML2 является возможность превращать класс в иерархию внутренних структур. Это позволяет разбить сложный объект на составляющие - составные структуры, которые представляют группы времени выполнения.

В состав диаграммы поведения входят четыре основные диаграммы:

1) диаграмма прецедентов описывает типичные взаимодействия между пользователями системы и самой системой. В первой версии UML позиционировалась как диаграмма вариантов использования, которая демонстрировала основные функции системы для каждого типа пользо­вателей. Фактически прецеденты – это способ записи требований или вариант использования системы одним из актеров (пользователей). Пример диаграммы прецедентов показан на рисунке 4.5;

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

3) диаграмма конечных автоматов (или диаграмма состояний) демонстрирует со­стояния одного объекта и условия переходов из одного состояния в другое. Средством моделирования динамического поведения объекта является конечный автомат;

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

               а) диаграмма последовательностей отображает упорядоченное по времени взаимодействие объектов в процессе выполнения варианта использования, акцент делается именно на последовательность взаимодействия;

      б) коммуникационная диаграмма UML1 называлась диаграммой кооперации) - особый вид диаграмм взаимодействия, в которых внимание акцентируется на обмене данными между различными участниками взаимодействия;

      в) диаграмма обзора взаимодействий - комбинация диаграмм деятельности и диаграмм последовательности, впервые появилась в UML2;

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

Рисунок 4.5 – Пример диаграммы прецедентов

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

Дополнениями к диаграммам служат формализованные и неформализо­ванные текстовые описания, комментарии и словари. При построении этих и других диаграмм используют унифицированную систему обозначений. UML и предлагаемая теми же авторами методика Rational Unified Process поддерживаются пакетом Rational Rose фирмы Rational Software Corporation. Ряд диаграмм UML можно построить также средствами про­граммы Microsoft Visual Modeler и других CASE-средств.

 

5 глава. Пользовательские интерфейсы

 

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

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

С распространением персональных компьютеров невероятно возрос­ло число их пользователей, в том числе не имеющих даже начальных знаний в области вычислительной техники. Значительно увеличилось и число программирующих пользователей ЭВМ, как имеющих соответствующую базовую подготовку, так и «самоучек», в распоряжении которых теперь имеются мощные средства разработки, позволяющие создавать программы с практически неограниченными интерактивными возможностями. Наконец наличие такого уникального средства общения, как Интернет, позволяет всем желающим выставлять на всеобщее обозрение плоды своего творчества, вне зависимости от их качества и предназначения.

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

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

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

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

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

 


5.1 Основные понятия

 

Сложность понятия «пользовательский интерфейс» породила множество опреде­лений, которые менялись в процессе развития самого пользовательского интер­фейса.

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

- набор задач пользователя, которые он решает при помощи системы;

- используемая системой метафора (например, рабочий стол в Windows);

- элементы управления системой;

- навигация между блоками системы;

- визуальный (и не только) дизайн экранов программы;

- средства отображения информации, отображаемая информация и форматы;

- устройства и технологии ввода данных;

- диалоги, взаимодействие и транзакции между пользователем и компьютером;

- обратная связь с пользователем;

- поддержка принятия решений в конкретной предметной области;

- порядок использования программы и документация на нее.

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

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

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

Сообщение - порция информации, участвующая в диалоговом обмене. Различают:

а)     входные сообщения, которые генерируются человеком с помощью средств ввода: клавиатуры, манипуляторов, например мыши;

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

Рисунок 5.1 - Организация взаимодействия компьютера и пользователя

 

В основном пользователь генерирует сообщения следующих типов:

- за­прос информации;

- запрос помощи;

- запрос операции или функции;

- ввод или изменение информации;

- выбор поля кадра и т. д.

В ответ пользователь получает от компьютера:

- под­сказки или справки;

- информационные сообщения, не требующие ответа;

- приказы, требующие действий;

- сообщения об ошибках, нуждающиеся в от­ветных действиях;

- изменение формата кадра и т. д.

 

5.2 Виды пользовательских интерфейсов

 

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

1) командный интерфейс;

2) графический интерфейс;

3) речевой интерфейс;

4) мимический интерфейс;

5) семантический интерфейс.

 

5.2.1 Командный интерфейс.

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

Командный интерфейс реализован в виде комбинации пакетной технологии и технологии командной строки.

Исторически пакетная технология появилась первой (Германия, 1937). Идея ее проста: на вход компьютера подается последовательность символов, в которых по определенным правилам указывается последовательность запущенных на выполнение программ. После выполнения программы запускается следующая по очередности и т.д. Машина по определенным правилам находит для себя команды и данные. В качестве последовательности может выступать перфолента, стопка перфокарт, последовательность нажатия клавиш электрической пишущей машинки. Машина также выдает свои сообщения на перфоратор, алфавитно-цифровое печатающее устройство, ленту пишущей машинки. Такая машина представляет собой «белый шкаф», в который постоянно подается информация и которая также постоянно информирует о своем состоянии. Пользователь практически не оказывает влияния на работу машины, поскольку он может лишь приостановить работу машины, сменить программу и вновь запустить компьютер.

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

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

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

Преобладающим видом файлов при работе с командным интерфейсом стали текстовые файлы - только их можно было создать при помощи клавиатуры. Интерфейс командной строки активно использовался  в UNIX.

 

5.2.2 Графический интерфейс.

Идея появления графического интерфейса зародилась в середине 70-х годов ХХ века, когда в исследовательском центре Xerox Palo Alto Research Center (PARC) была разработана концепция визуального интерфейса. Его реализация стала возможной благодаря развитию технической базы компьютеров, уменьшению времени реакции компьютера на команду, а также увеличению объема оперативной памяти.

Первая система с графическим интерфейсом 8010 Star Information System группы PARC появилась в 1981 году. Первоначально визуальный интерфейс использовался только в программах. Постепенно он стал переходить и на операционные системы, используемых сначала на компьютерах Atari и Apple Macintosh, а затем и на IBM-совместимых компьютерах.

Характерной особенностью графических интерфейсов является то, что диалог с пользователем ведется не явно с помощью команд, а через графические образы. Этот вид интерфейса реализован на технологиях простого графического интерфейса и «чистого» WIMP - интерфейса.

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

- при отображении символов допускалось выделение части символов цветом, инверсным изображением, подчеркиванием и мерцанием, благодаря чему повысилась выразительность изображения;

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

- реакция на нажатие любой клавиши во многом зависела от того, в какой части экрана находился курсор;

- на клавиатуре стали использоваться «серые» клавиши управления курсором;

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

Появление этого типа интерфейса совпало с широким распространением операционной системы MS DOS. Простой графический интерфейс использовался в файловой оболочке Nortron Commander, редакторах Multi-Edit, Лексикон, ChiWriter и текстовый процессор Microsoft Word for Dos.

Вторым этапом в развитии графического интерфейса стал «чистый» интерфейс WIMP (Window - окно, Image - образ, Menu - меню, Pointer – указатель), который обладает следующими особенностями:

- работа с программами, файлами и документами ведется в окнах;

- программы, файлы, документы, устройства и другие объекты представляются в виде значков – иконок, которые при открытии превращаются в окна;

- действия с объектами осуществляются с помощью меню, которое становится основным элементом управления;

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

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

Этот вид интерфейса наиболее прост в усвоении и интуитивно понятен. Ярким примером программ с графическим интерфейсом является операционная система Microsoft Windows.

 

5.2.3 Речевой интерфейс.

В середине 90-х годов ХХ века, после появления недорогих звуковых карт и широкого распространения технологий распознавания речи, была разработана так называемая «речевая технология» - простейшая реализация SILK - интерфейса.

SILK - интерфейс (Speech - речь, Image - образ, Language - язык, Knowlege - знание) наиболее приближен к обычной, человеческой форме общения. Согласно технологии команды подаются голосом путем произнесения специальных зарезервированных слов – команд, т.е. ведется обычный «разговор» пользователя и компьютера. При этом компьютер находит для себя команды, анализируя человеческую речь и находя в ней ключевые фразы. Результат выполнения команд он также преобразует в понятную пользователю форму.

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

 

5.2.4 Мимический интерфейс.

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

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

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

 

5.2.5 Семантический (общественный) интерфейс.

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

Его основная отличительная черта - это отсутствие команд при общении с компьютером. Запрос формируется на естественном языке, в виде связанного текста и образов. Фактически - это моделирование «общения» пользователя с компьютером.

С середины 90-х годов XX века в связи с важным военным значением этих разработок это направление было засекречены.

 

5.3 Типы пользовательских интерфейсов

 

Различают два основных подхода к разработке интерфейсов: процедурно-ориентированный и объ­ектно-ориентированный подходы  (см. рисунок 5.2).

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

Реализация современного процедурно-ориентированного пользователь-ского интерфейса на базе струк­турного подхода является очень сложной и трудоемкой задачей.

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

Элементы интерфейсов данного типа включены в пользова­тельский интерфейс Windows.

Рисунок 5.2 - Типы интерфейсов

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

Среди процедурно-ориентированных интерфейсов различают три типа: примитивные, меню и со свободной навигацией [22].

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

 

Таблица  5.1 – Основные отличия пользовательских моделей интерфейсов

Процедурно-ориентированные пользовательские интерфейсы

Объектно-ориентированные пользовательские интерфейсы

Обеспечивают пользователей функциями, необходимыми для выполнения задач      

Обеспечивают пользователям возможность взаимодействия с объектами

Акцент делается на задачи

Акцент делается на входные данные и результаты

Пиктограммы представляют приложения, окна или операции

Пиктограммы представляют объекты

Содержание папок и справочников отображается с помощью таблиц и списков          

Папки и справочники являются визуальными контейнерами объектов

 

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

Интерфейсы со свободной навигацией также называют графическими пользовательскими интерфейсами (GUI - Graphic User Interface) или интер­фейсами WYSIWYG (What You See Is What You Get - что видишь, то и полу­чишь, т. е. что пользователь видит на экране, то он и получит при печати). Эти названия подчеркивают, что интерфейсы данного типа ориентированы на использование экрана в графическом режиме с высокой разрешающей способностью.

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

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

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

 

5.4 Особенности разработки пользовательских интерфейсов

 

При проектировании пользовательских интерфейсов необходимо учиты­вать психофизические особенности человека, связанные с восприятием, за­поминанием и обработкой информации. Исследованием принципов работы мозга человека занимается когнитив­ная психология [16].

Информация о внешнем мире поступает в мозг в огромных количе­ствах. При этом краткосрочная память является своего рода оперативной памятью мозга, невостребованная ин­формация хранится в ней не более 30 секунд. Ее емкость приблизительно равна 7 ± 2 несвязанных объектов. Чтобы не забыть важ­ную информацию, мы обычно повторяем ее «про себя», «обновляя» информацию в краткосрочной памяти. Поэтому при проектировании интерфейсов следует иметь в виду, что большинству людей сложно, например, запомнить и ввести на другом экране число, содержащее более 5 цифр (7 - 2), или некоторое сочетание букв.

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

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

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

В интерфейсах звук использу­ют с разными целями:

- для привлечения внимания;

- как фон, обеспечивающий некоторое состояние пользователя;

- как источник дополнительной информа­ции.

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

Человеку свойственно субъектив­ное восприятие времени. Считают, что внутреннее время связано со скоро­стью и количеством воспринимаемой и обрабатываемой информации. Заня­тый человек времени не замечает. Зато в состоянии ожидания время тянется бесконечно: в это время мозг оказывается в со­стоянии информационного вакуума. Доказано, что при ожидании более 1-2 секунд пользователь может отвлечься, «потерять мысль», что увеличивает усталость и неблагоприятно сказывается на результатах работы. Сократить время ожидания можно, заняв пользователя, но не отвлекая его от работы. Например, предоставить ему какую-либо информацию для обдумывания или  выводить промежуточные результаты.

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

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

Существуют три модели пользовательского ин­терфейса: модель программиста, модель пользователя, программная мо­дель.

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

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

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

Рисунок 5.3 - Процесс разработки пользовательского интерфейса

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

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

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

1) следует помнить, что обязанность интерфейса – обеспечить взаимодействие пользователя и компьютера;

2) интерфейс должен быть понятным: для его эффективного использования пользователь должен понимать, что именно представляет интерфейс, какие задачи можно выполнять с его помощью, к чему приведет то или иное действие;

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

4) пользователь должен чувствовать, что ситуация под его контролем; для этого следует периодически отображать состояние системы, описывать причинно-следственные связи («если вы сделаете …, то случится …») и давать понять пользователю, чего можно ожидать от каждой конкретной операции;

5) лучшее управление - прямое управление: интерфейс должен быть максимально незаметным и способным распознавать естественные человеческие жесты, тогда у пользователя появится ощущение, будто он управляет объектом напрямую;

6) каждый отдельный экран приложения должен служить для выполнения какой-либо одной задачи, стоящей перед пользователем;

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

8) пользователь должен понимать, как поведет себя тот или иной элемент интерфейса, едва взглянув на него, следовательно, несхожие в поведении элементы  должны оформляться по-разному;

9) следует обращать внимание на четкость визуальной иерархии: элементы на экране должны каждый раз располагаться в определенном порядке;

10) грамотная организация контента может значительно снизить когнитивную нагрузку пользователей;

11) цветом можно выделять объекты, привлекая к ним внимание пользователей, но при этом элементы нельзя разделять только по цвету: если предполагается работать с каким-либо элементом продолжительное время или элемент содержит объемный текст, рекомендуется использовать для оформления бледные или приглушенные тона, а яркие оттенки - для расстановки акцентов;

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

13) подсказки должны быть контекстно-зависимыми и появляться только тогда и там, где они нужны, в остальное время оставаясь скрытыми;

14) первый экран, который видит пользователь, не должен быть пустым - на нем должны содержаться указания и подсказки для быстрого начала работы;

15) интерфейс, ориентированный на решение потенциальных проблем, никому не нужен: следует разрабатывать интерфейс в соответствии с актуальными проблемами.

Кроме того, необходимо:

- проектировать и разрабатывать интерфейс пользователя как от­дельный компонент создаваемого приложения;

- учитывать возможности и особенности аппаратно-программных средств, на базе которых реализуется интерфейс;

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

 

6 глава. Тестирование и отладка программных продуктов

 

6.1 Основы тестирования программного обеспечения

 

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

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

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

 

6.1.1 Основные принципы организации процесса тестирования.

Процесс разработки согласно современной модели жизненного цикла программного обеспечения предполагает три стадии тестирования:

-   автономное тестирование компонентов программного обеспечения;

-   комплексное тестирование программного обеспечения;

-   системное или оценочное тестирование на соответствие основным критериям качества.

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

а)     предполагаемые результаты должны быть известны до тестирования;

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

в)    необходимо досконально изучать результаты каждого теста;

г)     необходимо проверять действия программы на неверных данных;

д)    необходимо проверять программу на неожиданные побочные эффекты на неверных данных.

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

 

6.1.2 Основные подходы и методы тестирования.

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

Структурный подход базируется на том, что известна структура тести­руемого программного обеспечения, в том числе его алгоритмы («стеклян­ный ящик»). Тесты строятся для проверки правильности реализации заданной логики в коде программы.

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

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

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

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

Различают статический и динамический подходы к ручному контролю. При статическом подходе анализируют структуру, управляющие и инфор­мационные связи программы, ее входные и выходные данные. При динамическом - выполняют ручное тестирование (вручную моделируют про­цесс выполнения программы на заданных исходных данных).

Исходными данными для таких проверок являются: техническое зада­ние, спецификации, структурная и функциональная схемы программного продукта, схемы отдельных компонентов, а для более поздних этапов - алгоритмы и тексты программ, а также тестовые наборы. Доказано, что ручной контроль способствует существенному увеличе­нию производительности и повышению надежности программ и с его помо­щью можно находить от 30 до 70 % ошибок логического проектирования и кодирования.

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

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

Одним из самых сложных является вопрос о завершении тестирования, так как невозможно гарантировать, что в программе не осталось ошибок. Часто тестирование завершают потому, что закончилось время, отведен­ное на его выполнение. Его сворачивают, обходясь минимальным тестированием [19], которое предпо­лагает: тестирование граничных значений, тщательную проверку руководства, тестирование минимальных конфигураций технических средств, возможности редактирования команд и повторения их в любой последовательности, устойчивости к ошибкам пользователя.

После завершения комплексного тестирования приступают к оценочному тестированию, целью которого является поиск несоответствий техническому заданию. Оценочное тестирование включает:

- тестирование удобства использования;

- тестирование на предельных объемах;

- тестирование на предельных нагрузках;

- тестирование удобства эксплуатации;

- тестирование защиты;

- тестирование производительности;

- тестирование требований к памяти;

- тестирование конфигурации оборудования;

- тестирование совместимости;

- тестирование удобства установки и обслуживания;

- тестирование надежности;

- тестирование восстановления;

- тестирование документации.

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

1) главное правило тестирования - не избегайте тестирования;

2) практически доказано: чем лучше изначально написан код, тем меньше ошибок он будет содержать;

3) тестирование граничных условий непосредственно при написании кода - эффективный способ удалить множество мелких глупых ошибок;

4) необходимо активно использовать автоматизированное тестирование, поскольку машины не делают ошибок, не устают и не занимаются самообманом;

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

 

6.2 Отладка программного обеспечения

 

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

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

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

 

6.2.1 Классификация ошибок.

В зависимости от этапа обработки, на котором могут проявляться ошибки, различают:

а)     синтаксические ошибки – сопровождаются комментарием с указанием их мес­тоположения, фиксируются компилятором (транслятором) при выполнении синтаксического и частично се­мантического анализа;

б)    ошибки компоновки - обнаруживаются компоновщиком (редакто­ром связей) при объединении модулей программы;

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

1)  ошибки определения исходных данных (ошибки передачи, ошибки преобразования, ошибки перезаписи и ошиб­ки данных);

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

3)  ошибки накопления погрешностей результатов вычислений (игнорирование ограничений разрядной сетки и способов уменьшения погрешности).

 

 

6.2.2 Методы обнаружения ошибок.

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

а)     ручного тестирования (при обнаружении ошибки нужно выполнить те­стируемую программу вручную, используя тестовый набор, при работе с ко­торым была обнаружена ошибка);

б)    индукции (метод основан на тща­тельном анализе симптомов ошибки, которые могут проявляться как неверные результаты вычислений или как сообщение об ошибке);

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

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

Для получения дополнительной информации об ошибке выпол­няют добавочные тесты и используют специальные методы и средства:

- отладочный вывод;

- интегрированные средства отладки;

- независимые отладчики.

Общая методика отладки программных продуктов, написанных для выполнения в операционных системах MS DOS и Win32, предполагает:

1  этап - изучение проявления ошибки;

2  этап – определение локализации ошибки;

3 этап - определение причины ошибки;

4 этап — исправление ошибки;

5 этап - повторное тестирование.

Процесс отладки можно существенно упрос­тить, если следовать основным рекомендациям структурного подхода к про­граммированию:

а)     программу наращивать «сверху-вниз», от интерфейса к обрабатываю­щим подпрограммам, тестируя ее по ходу добавления подпрограмм;

б)    выводить пользователю вводимые им данные для контроля и прове­рять их на допустимость сразу после ввода;

в)    предусматривать вывод основных данных во всех узловых точках ал­горитма (ветвлениях, вызовах подпрограмм).

 


7 глава. Составление программной документации

 

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

Составление программной документации - важный процесс. На каждый про­граммный продукт должна разрабатываться документация двух типов [16]: для пользовате­лей различных групп и для разработчиков. Отсутствие документации любого типа для конкретного программного обеспечения недопустимо.

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

Документирование программного обеспечения осуществляется в со­ответствии с Единой системой программной документации (ГОСТ 19.ХХХ).

В Республике Казахстан с этой целью разработаны и используются стандарты:    СТ РК ИСО/МЭК 6592 «Руководство по документированию компьютерных прикладных систем» и СТ РК 34.010-2002 «Информационная технология. Порядок проведения экспертизы программной документации».

Оба стандарта базируются на документе ГОСТ 19.101-77, который устанавливает виды программных документов для программного обеспечения различных типов.

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

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

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

Следующим по важности документом является программа и методика испытаний (ПМИ). Структурно она подобна ТЗ: практически для каждого пункта ТЗ в ПМИ говорится, как этот пункт будет проверяться. Способы проверки могут быть самыми разными – от пропуска специального теста до изучения исходных текстов программы, но они должны быть предусмотрены заранее, а не придумываться в момент испытаний. Новички приступают к составлению ПМИ непосредственно перед завершением работ, а опытные руководители составляют и согласовывают с заказчиками одновременно с ТЗ. Хорошо составленная ПМИ является гарантией успешной сдачи работ.

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

Руководство оператора (пользователя) – это основной документ, описывающий, как пользоваться системой [11]. В хорошем руководстве сначала описывается идея системы, основные функции и как ими пользоваться, а уже потом идет описание всех клавиш и меню.

Руководство программиста - это самый объемный документ, описывающий внутреннюю организацию программы. Обычно этот документ идет в паре с документом «Текст программы» – одностраничным документом с оглавлением дискеты или CD. Руководство программиста дает заказчику возможность дописать новые фрагменты программы или переделать старые. В современной литературе этот документ называется SDK (Software Development Kit). Продукт, снабженный SDK, может стоить на порядок дороже, чем такой же продукт без него.

Сейчас не принято продавать исходные тексты программ – проблемы с интеллектуальной собственностью. Даже при наличии SDK трудно «влезть» в чужую программу – как говорится, себе дороже. Поэтому большое распространение получили API (Application Program Interface). Программа передается только в виде DLL (библиотека двоичных кодов), при этом известно, как обратиться к каждой функции из других программ, т.е. известно имя точки входа, количество, типы и значения параметров. Наличие множества API, конечно, хуже, чем наличие исходных текстов (например, нельзя переделать что-то в середине функции), зато много проще в использовании.

С другой стороны, все большую популярность приобретает FSF (Free Software Foundation). Основателем этого движения был Ричард Столман [32], который забил тревогу по поводу попыток крупных фирм запатентовать многие основные алгоритмы и программы: «Дойдет до того, что они запатентуют понятия цикл и подпрограмма, что мы будем тогда делать?».

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

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

 

Заключение

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

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

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

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

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

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

 

Приложение А

Образец выполнения технического задания

 

ТЕХНИЧЕСКОЕ ЗАДАНИЕ НА РАЗРАБОТКУ СИСТЕМЫ УЧЕТА УСПЕВАЕМОСТИ СТУДЕНТОВ

 

1 Введение

 

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

 

2 Основание для разработки

 

Система разрабатывается на основании приказа декана теплоэнергетического факультета № 15 от 24 сентября 2011 г. и в соответствии с планом мероприятий по совершенствованию учебного процесса на 20112012 учебный год.

 

3 Назначение

 

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

 

4 Требования к программе или программному изделию

 

4.1 Требования к функциональным характеристикам

4.1.1 Система должна обеспечивать возможность выполнения следующих функций:

- инициализацию системы (ввод списков групп, перечней дисциплин и т. п.);

- ввод и коррекцию текущей информации о ходе сдачи сессии конкретными студентами;

- хранение информации об успеваемости в течение времени обучения студента;

- получение сведений о текущем состоянии сдачи сессии студентами.

4.1.2 Исходные данные:

- списки студентов учебных групп;

- учебные планы кафедр;

- расписания сессий;

- текущие сведения о сдаче сессии каждым студентом.

4.1.3 Результаты:

- итоги сдачи сессии конкретным студентом;

- итоги сдачи сессии студентами конкретной группы;

- процент успеваемости по всем студентам группы при сдаче конкретного пред­мета в целом на текущий момент;

- проценты успеваемости по всем группам специальности на текущий момент;

- проценты успеваемости по всем группам курса на текущий момент;

- проценты успеваемости по всем курсам и по факультету на текущий момент;

- список задолжников группы на текущий момент;

- список задолжников курса на текущий момент.

 

4.2  Требования к надежности

4.2.1. Предусмотреть контроль вводимой информации.

4.2.2. Предусмотреть блокировку некорректных действий пользователя.

4.2.3.  Обеспечить целостность хранимой информации.

 

4.3 Требования к составу и параметрам технических средств

4.3.1. Система должна работать на IBM совместимых персональных компьюте­рах.

4.3.2. Минимальная конфигурация: тип процессора - Pentium и выше; объем оперативного запоминающего устройства - 32 Мб и более.

 

4.4 Требования к информационной и программной совместимости

Система должна работать под управлением семейства ОС Windows.

 

5 Требования к программной документации

 

5.1   Разрабатываемые программные модули должны быть самодокументирова­ны, т.е. тексты программ должны содержать все необходимые комментарии.

5.2 Программная система должна включать справочную информацию о работе и подсказки пользователю.

5.3   В состав сопровождающей документации должны входить:

5.3.1 Пояснительная записка, содержащая описание разработки.

5.3.2 Руководство системного программиста.

5.3.3 Руководство пользователя.

5.3.4 Графическая часть на трех листах формата А3 (блок-схемы алгоритмов): структурная схема; диаграмма компонентов данных; формы интерфейса пользователя.

 

6 Этапы разработки

 

Название этапа

Срок

Отчетность

1

Проектирование программного продукта

01.10.2011-01.11.2011   

Разработка технического задания и уточнение спецификаций. Принятие принципиальных решений. Алгоритмов решения задачи. Проек-тирование структурной и функциональной схем системы учета успеваемости. 

2

Реализация

01.12.2011-29.02.2012                                                              

Описание внутренних форматов, интерфейса и форматов данных базы. Реализация систе­мы на уровне интерфейса. Реализация программных модулей задачи.

3

Тестирование  и составление документации 

01.03.2012-30.04.2012   

Результаты тестов.

Программная документация.


 Список литературы

1.         Аляев Ю.А., Козлов О.А. Алгоритмизация и языки программ-мирования Pascal, C++, Visual Basic. – М.: Финансы и статистика, 2004.

2.         Арлоу Д., Нейштадт И. UML2 и Унифицированный процесс. Практический объектно-ориентированный анализ и проектирование. – СПб.: Символ-Плюс, 2007.

3.         Ашарина И.В. Основы программирования на языках С и С++.- М.: Горячая линия - Телеком, 2002.

4.         Бахман П., Френцель М., Ханцшманн К и др. Программные системы. – М.: Мир, 1988.

5.         Бек Кент. Экстремальное программирование — СПб: Питер, 2002.

6.         Буч Г., Рамбо Д., Джекобсон А. Язык UML. Руководство пользователя. – М.: ДМК Пресс, 2001.

7.         Вендров А.М. CASE-технологии. Современные методы и средства проектирования информационных систем. - М.: Финансы и статистика, 1998.

8.         Вирт Н. Алгоритмы и структуры данных. – М.: Мир, 1989.

9.         Гома Х. UML-проектирование систем реального времени параллельных и распределенных приложений. – М.: ДМК Пресс, 2011.

10.    ГОСТ 19.701-90 ЕСПД. Схемы алгоритмов, программ, данных и систем. Условные обозначения и правила выполнения. – М.: Изд-во стандартов, 1990.

11.    Гримм С.Дж. Как писать руководства для пользователей. – М.: Радио и связь, 1985.

12.    Евстигнеев В.А., Городняя Л.В., Густокашина Ю.В. Язык функционального программирования SISAL. Интеллектуализация и качество программного обеспечения. - Новосибирск, 1994.

13.    Ершов А.П. Научные основы доказательного программирования. Избранные труды. - Новосибирск, Наука, 1994.

14.    Жоголев Е.А. Технологические основы модульного программирования. - М.: Программирование, 1980.

15.    Иванов Д., Новиков Ф. Моделирование на UML. Учебно-методическое пособие. – СПб.: СПбГУ ИТМО, 2010.

16.    Иванова Г.С. Технология программирования. - М.: Изд-во МГТУ им. Н.Э.Баумана, 2002.

17.    Иванова Г.С. Основы программирования. - М.: Изд-во МГТУ им. Н.Э.Баумана, 2001.

18.    Иванова Г.С., Ничушкина Т.Н., Пугачев Е.К. Объектно-ориентированное программирование: учебник для вузов. – М.: Изд-во МГТУ им. Н.Э.Баумана, 2001.

19.    Канер С., Фолк Д., Нгуен Е.К. Тестирование программного обеспечения. – Киев, ДиаСофт, 2000.

20.    Кантор М. Управление программными проектами. Практическое руководство по разработке успешного программного обеспечения. - М.: Вильямс, 2002.

21.    Кватрани Т. Rational Rose 2000 и UML. Визуальное моделирование. - М.: ДМК Пресс, 2001.

22.    Мандел Т. Разработка пользовательского интерфейса. – М.: ДМК Пресс, 2001.

23.    Майерс Г. Надежность программного обеспечения. - М.: Мир, 1980.

24.    Непейвода Н.Н. Стили и методы программирования. Курс лекций. -  М.: Интернет-университет информационных технологий, 2005.

25.    Орлов С. Технологии разработки программного обеспечения: Учебник - СПб.: Питер, 2002.

26.    Поликарпова Н.И., Шалыто А.А. Автоматное программирование. — СПб.: Питер, 2009.

27.    Попов В.Б. Основы информационных и телекоммуникационных технологий. Программные средства информационных технологий. – М.: Финансы и статистика, 2005.

28.    Роберт В. Себеста. Основные концепции языков программирования = Concepts of Programming Languages. — М.: Вильямс, 2001.

29.    Сик Джереми, Ли Лай-Кван, Ламсдэйн Эндрю. C++ Boost Graph Library. ­- СПб.: Питер, 2006.

30.    Соммервиль И. Инженерия программного обеспечения. - М.: Изд-во Вильямс, 2002.

31.    Тассел Д. Ван. Стиль, разработка, эффективность, отладка и испытание программ. – М.: Мир, 1985.

32.    Терехов А.Н. Технология программирования. – М.: БИНОМ,  Интернет-университет информационных технологий, 2006.

33.    Фаулер М., Скотт К. UML в кратком изложении. Применение стандартного языка объектного моделирования. – М.: Мир, 1999.

34.    Фаулер М. UML. Основы. – СПб: Символ-Плюс, 2005.

35.    Филд А., Харрисон П. Функциональное программирование. - М.: Мир, 1993.

36.    Хендерсон П. Функциональное программирование. Применение и реализация. - М.: Мир, 1983.

37.    Хьюз Дж., Мичтом Дж. Структурный подход к программированию. - М.: Мир, 1985.

38.    Шалыто А.А. Switch-технология. Алгоритмизация и программирование задач логического управления. — СПб.: Наука, 1998.

39.    Henning M. The Rise and Fall of CORBA. - ACM Queue, Volume 4, Number 5, 2006.

40.    Raccoon L. The Chaos Model and the Chaos Life Cycle. - ACM Press:  ACM Software Engineering Notes, Volume 20, Number 1, 1995.

41.    http://citforum.ru/operating_systems/windows/complus

42.    http://www.PowerBuilder.sbn.bz