![]() |
Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | |
|
Проектирование алгоритмов и программ — наиболее ответственный этап жизненного цикла программного продукта, определяющий, насколько создаваемая программабудет соответствовать требованиям конечного пользователя. Затраты на создание, сопровождение и эксплуатацию программных продуктов, научно-технический уровень их разработки, время морального устаревания и многое другое - все это также зависит от проектных решений.
Методы проектирования алгоритмов и программ очень разнообразны, их можно классифицировать по различным признакам, главные из которых — степень автоматизации проектных работ и принятая методология процесса разработки.
По степени автоматизации проектирования алгоритмов и программ можно выделить:
методы традиционного (неавтоматизированного) проектирования;
методы автоматизированного проектирования (CASE-технология и ее элементы).
Неавтоматизированное проектирование алгоритмов и программ используется при разработке небольших по трудоемкости и структурной сложности программных продуктов, не требующих участия большого числа разработчиков (программные продукты при этом часто имеют прикладной характер). При нарушении указанных ограничений производительность труда разработчиков заметно снижается, падает качество программного продукта, увеличиваются затраты труда и прочие издержки.
Автоматизированное проектирование возникло в связи с необходимостью уменьшить затраты на проектные работы, сократить сроки их выполнения, создать типовые заготовки алгоритмов и программ, многократно тиражируемых для различных разработок, а также для координации работ большого коллектива разработчиков, стандартизации их действий.
Автоматизация проектирования может охватывать все или только отдельные этапы жизненного цикла программного продукта; эти этапы могут быть изолированы друг от друга либо составлять единый комплекс работ, выполняемый последовательно. Как правило, автоматизированный подход требует технического и программного «перевооружения» самих разработчиков (использования более мощных компьютеров, дорогостоящего программного инструментария, повышения квалификации программистов и т.д.). Это под силу лишь достаточно крупным фирмам, специализирующимся на разработке определенного класса программных продуктов и занимающих устойчивое положение на рынке программных средств.
Проектирование алгоритмов и программ может основываться на различных подходах, среди которых наиболее распространены:
алгоритмическое программирование;
структурное проектирование;
объектно-ориентированное проектирование.
Алгоритмическое программирование
Алгоритм, как уже отмечалось, это формальное описание способа решения задачи путем разбиения ее на конечную по времени последо-
вательность действий (элементарных операций). Под словом «формальное» подразумевается, что описание должно быть абсолютно полным и учитывать все возможные ситуации, которые могут встретиться по ходу решения. Под элементарной операцией понимается действие, которое по заранее определенным критериям (например, очевидности) не имеет смысла детализировать.
Основная идея алгоритмического программирования - разбиение программы на последовательность модулей, каждый из которых выполняет одно или несколько действий. Единственное требование к модулю - его выполнение всегда должно начинаться с первой команды и заканчиваться последней (это значит, что невозможно перейти к командам модуля извне, минуя его начало, и передать управление из модуля на другие команды в обход заключительной).
Алгоритм на выбранном языке программирования записывается с помощью команд описания данных, вычисления значений и управления последовательностью выполнения программы. При этом предполагается, что текст программы представляет собой линейную последовательность операторов присваивания, цикла и условных операторов. Таким способом удобно решать не очень сложные задачи и составлять программы, содержащие несколько сот строк кода. За этими пределами понятность исходного текста резко падает из-за того, что общая структура алгоритма теряется за конкретными операторами языка, детально описывающими элементарные действия. Возникают многочисленные вложенные условные операторы и операторы циклов, логика программы становится запутанной, при попытке исправить один ошибочный оператор неизбежно возникают новые ошибки, связанные с особенностями его работы (поскольку результаты его выполнения могут использоваться в самых разных местах программы). В результате отладить длинную линейную последовательность операторов оказывается практически невозможным.
Структурное проектирование
В основе структурного проектирования лежит целенаправленное структурирование задачи на отдельные составляющие. Типичными методами структурного проектирования являются:
структурное программирование;
нисходящее проектирование;
модульное программирование;
событийно-ориентированное программирование.
В зависимости от объекта структурирования различают функционально-ориентированные методы (последовательное разложение задачи или целостной проблемы на отдельные, достаточно простые составляющие, обладающие функциональной определенностью) и методы структурирования данных.
При использовании функционально-ориентированных методов в первую очередь учитывают заданные функции обработки данных, в соответствии с которыми определяется состав и логика работы (алгоритмы) отдельных компонентов программного продукта. С изменением содержания функций обработки, их состава, соответствующего им информационного входа и выхода требуется перепроектирование программного продукта. Основной упор в структурном подходе делают на моделировании процессов обработки данных.
Структурирование данных предполагает создание их эффективных моделей, применительно к которым и устанавливают необходимый состав функций и процедур обработки. Программные продукты оказываются тесно связанными со структурами обрабатываемых данных, изменение которых отражается на логике обработки (алгоритмах) и обязательно требует перепроектирования программного продукта.
Очевидны следующие преимущества структурного проектирования:
маленькие модули можно написать относительно легко и быстро; модули общего назначения можно использовать неоднократно, что заметно ускоряет разработку новых программ;
отдельные модули можно отлаживать и тестировать независимо от программы в целом.
При создании средних по размеру приложений (несколько тысяч строк исходного кода) используют структурное программирование, основная идея которого заключается в том, что структура программы должна отражать структуру решаемой задачи, а алгоритмрешения должен быть ясно виден из исходного текста. Для этого надо иметь средства для создания программы не только с помощью простых операторов, но и с помощью средств, более точно отражающих конкретную структуру алгоритма. С этой целью в программирование было введено понятие подпрограммы - набора операторов, выполняющих нужное действие и не зависящих от других частей исходного кода.
Программа разбивается на множество мелких подпрограмм (включающих до 50 операторов — это критический порог для быстрого понимания цели подпрограммы), каждая из которых выполняет одно из действий, предусмотренных исходным заданием. Комбинируя готовые подпрограммы, удается формировать итоговый алгоритмуже не из простых операторов, а из законченных блоков, имеющих определенную смысловую нагрузку, причем обращаться к таким блокам можно по названиям. Подпрограммы фактически становятся новыми операторами языка, определяемыми самим программистом.
Возможность применения подпрограмм означает, что язык программирования относится к классу процедурных языков.
Наличие подпрограмм позволяет также вести проектирование и разработку приложения «сверху вниз»; такой подход называется нисходящим проектированием. Сначала выделяется несколько подпрограмм, решающих глобальные задачи (например, инициализация данных, главная часть вычислений, завершение программы), а потом каждый из этих модулей детализируется на более низком уровне, также с разбиением на несколько подпрограмм; процесс продолжается до тех пор, пока вся задача не окажется реализованной.
Такой подход удобен тем, что позволяет программисту постоянно мыслить на предметном уровне, не отвлекаясь на конкретные операторы и переменные. Кроме того, появляется возможность некоторые подпрограммы не записывать сразу, а временно откладывать их подготовку, пока не будут закончены другие, более важные части. Например, если имеется необходимость вычисления сложной математической функции, выделяется отдельная подпрограмма такого вычисления, но реализуется она временно одним оператором, который просто присваивает заранее выбранное значение (например, 5).
Когда все приложениебудет написано и отлажено, можно приступить к реализации этой функции.
Следует учитывать, что небольшие подпрограммы значительно проще отлаживать, поэтому данный подход существенно повышает общую надежность программы в целом.
Другое важное преимущество подпрограмм - возможность их повторного использования. С интегрированными системами программирования обычно поставляются большие библиотеки стандартных подпрограмм, которые позволяют значительно повысить производительность труда разработчиков за счет использования уже готовых блоков программного кода.
Модульное программирование базируется на использовании логически взаимосвязанной совокупности функциональных элементов (модулей), характеризующихся следующими особенностями:
наличие одного входа и одного выхода - на входе программный модуль получает определенный набор исходных данных, выполняет содержательную обработку и возвращает один набор результатных данных (так называемая модель вход-процесс-выход);
функциональная завершенность - модуль выполняет по каждой отдельной функции перечень регламентированных операций, достаточных для завершения начатой обработки;
логическая независимость (результат работы программного модуля зависит только от исходных данных, но не зависит от работы других модулей);
слабые информационные связи с другими программными модулями (обмен информацией между модулями должен быть минимальным);
обозримость по размеру и сложности.
Таким образом, модули обязательно содержат определение доступных для обработки данных, операции по их обработке, схемы взаимосвязи с другими модулями.
Каждый модуль состоит из спецификации и тела. Спецификации определяют правила использования модуля, а тело - способ реализации процесса обработки.
Принципы модульного программирования во многом сходны с принципами нисходящего проектирования. В обоих случаях сначала определяют состав и подчиненность функций, а затем набор программных средств, позволяющих их реализовать. Однотипные функции реализуются одним и тем же модулем. Функция верхнего уровня обеспечивается главным модулем; он управляет выполнением нижестоящих функций, которым соответствуют подчиненные модули.
При определении набора модулей, реализующих функции конкретного алгоритма, необходимо учитывать следующее:
каждый модуль вызывается на выполнение вышестоящим модулем, а закончив работу, возвращает управление вызвавшему модулю;
принятие основных решений в алгоритме выносится на максимально высокий уровень иерархии;
для использования в разных местах алгоритма одной и той же функции создается один модуль, который и вызывается по мере необходимости.
В результате дальнейшей детализации алгоритма создается функционально-модульная схема (ФМС) приложения, которая и является основой для его разработки.
Событийно-ориентированное программирование получило широкое распространение с возникновением операционной системы Windows и других разновидностей графического интерфейса пользователя. Идеология Windows с самого начала была основана на событиях. Щелчок на кнопке, выбор пункта меню, нажатие клавиши заставляет программу генерировать то или иное сообщение, которое отсылается соответствующему окну.
Структура программы при этом приобретает особый вид. Главная ее часть - бесконечный циклопроса, адресованный операционной системе, следящей за тем, не появилось ли новое сообщение. При его обнаружении вызывается подпрограмма, ответственная за обработку соответствующего события. Обработке подлежат не все события (их сотни), а только нужные. Цикл опроса продолжается, пока система не получит сообщение «завершить работу».
События могут быть пользовательскими (возникшими в результате действий пользователя), системными (например, при получении сообщения от системного таймера) и программными, генерируемыми самой программой (например, обнаружена ошибка и ее надо обработать).
Событийное программирование является развитием идей нисходящего проектирования; оно основано на определении и постепенной детализации реакции программы на различные события.
Объектно-ориентированное программирование
Развитие идей структурного и событийного программирования существенно подняло производительность труда программистов и позволило в разумные сроки (несколько месяцев) создавать приложения объемом в сотни тысяч строк. Однако такой объем уже приблизился к пределу возможностей человека, и потребовались новые технологии разработки программ. Основные ограничения на возможность создания больших систем накладывала разобщенность в программе данных и методов их обработки. Так, технологии, ориентированные на информационное моделирование, сначала специфицируют данные, а затем описывают процессы, их использующие. Технологии структурного подхода, наоборот, в первую
очередь описывают процессы обработки информации с последующим определением необходимых для этого данных и организации информационных потоков между связанными процессами.
В середине 80-х годов возникло новое направление - объектно-ориентированное программирование (ООП). Оно сочетает в себе лучшие идеи, воплощенные в структурном программировании, и новые концепции, позволяющие оптимально организовать программу. Объектно-ориентированная технология разработки программных продуктов объединяет данныеи процессы их обработки в новые логические сущности — объекты, каждый из которых может наследовать характеристики (методы и данные) других объектов, обеспечивая тем самым повторное использование программного кода.
Объектно-ориентированное программирование позволяет разложить проблему на связанные между собой задачи. Каждое событие, таким образом, становится самостоятельным объектом, содержащим свои собственные коды и данные, которые относятся к этому объекту. Реальные предметы окружающего мира обладают тремя базовыми характеристиками: они имеют набор свойств, способны разными методами изменять эти свойства и реагировать на события, возникающие как в окружающем мире, так и внутри самого объекта. Именно в таком виде и реализуется понятие объекта в ООП: 1) совокупность свойств (структур данных, характерных для этого объекта); 2) методы их обработки (подпрограммы изменения свойств) и 3) события, на которые данный объект может реагировать (и которые приводят, как правило, к изменению свойств объекта).
В результате каждый объект объединяет как типы данных, так и программы их обработки, что и позволяет отнести его к определенному классу. С помощью наследования классов один и тот же программный код можно использовать для самых различных объектов.
Механизм наследования - это, пожалуй, самое мощное свойство ООП. Без наследования объекты превращаются в простую комбинацию данных и подпрограмм, не дающую качественных преимуществ по сравнению с традиционными функциями и модулями. Наоборот, механизм наследования позволяет строить библиотеки по принципу «от простого к сложному». Вводя с помощью наследования новый объект в свою библиотеку, программист в максимальной степени использует уже созданные (и, возможно, отлаженные) объекты. Такой принцип конструирования программ называют восходящим программированием. В отличие от нисходящего, он не дает возможности поэтапного создания программы. Мелкие детали реализации объектов заслоняют собой генеральный алгоритм, поэтому при использовании ООП рекомендуется сочетание подходов.
Какими мощными средствами располагает объектно-ориентированное программирование, наглядно демонстрирует любой более или менее развитый графический интерфейс пользователя. Следует заметить, что преимущества ООП в полной мере проявляются лишь при разработке достаточно сложных программ. Правильно сконструированный объект располагает всеми необходимыми данными и процедурами их обработки, чтобы успешно реализовать требуемые от него действия. Таким образом, ООП в наибольшей степени подходит к задачам разработки библиотек программирования. Попытки использовать ООП для программирования несложных алгоритмических действий (например, связанных с вычислениями по готовым формулам) чаще всего приводят к искусственному нагромождению ненужных языковых конструкций.
Таким образом, объектно-ориентированный подход к проектированию программных продуктов основан: на выделении классов объектов; установлении характерных свойств объектов и методов их обработки; создании иерархии классов, наследовании свойств и методов. Он позволил резко повысить производительность труда программистов. Максимальный объем приложений, которые стали доступны для групп разработчиков численностью не более 10 человек, за несколько лет увеличился до миллионов строк кода. При этом одновременно удалось добиться высокой надежности программ и, что немаловажно, повторного использования ранее созданные объектов в других задачах.
Дата публикования: 2014-11-18; Прочитано: 1094 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!