Курс лекций информатика
.pdfмыши — в Windows генерируется подходящее сообщение, которое отсылается окну соответствующей программы.
Структура программы, созданной с помощью событийного программирования, следующая. Главная часть представляет собой один бесконечный цикл, который опрашивает Windows, следя за тем, не появилось ли новое сообщение. При его обнаружении вызывается подпрограмма, ответственная за обработку соответствующего события (обрабатываются не все события, их сотни, а только нужные), и подобный цикл опроса продолжается, пока не будет получено сообщение «Завершить работу».
События могут быть пользовательскими, возникшими в результате действий пользователя, системными, возникающими в операционной системе (например, сообщениями от таймера), и программными, генерируемыми самой программой (например, обнаружена ошибка, и ее надо обработать).
Событийное программирование является развитием идей нисходящего проектирования, когда постепенно определяются и детализируются реакции программы на различные события.
6.4.3. Объектно-ориентированное программирование
Развитие идей структурного и событийного программирования существенно подняло производительность труда программистов и позволило в разумные сроки (несколько месяцев) создавать приложения объемом в сотни тысяч строк. Однако такой объем уже приблизился к пределу возможностей человека, и потребовались новые технологии разработки программ. Основные ограничения на возможность создания больших систем накладывала разобщенность в программе данных и методов их обработки.
Традиционные подходы к разработке программных продуктов всегда подчеркивали различия между данными и методами их обработки. Так, технологии, ориентированные на информационное моделирование,
172
сначала специфицируют данные, а затем описывают процессы, использующие эти данные. Технологии структурного подхода ориентированы, в первую очередь, на процессы обработки данных с последующим установлением необходимых для этого данных и организации информационных потоков между связанными процессами.
В середине 80-х годов в программировании возникло новое направление, основанное на понятии объекта - объектно-ориентированное программирование (ООП). Оно сочетает в себе лучшие идеи воплощенные в структурном программировании и новые концепции, позволившие оптимально организовать программу. Объектно-ориентированная технология разработки программных продуктов объединяет данные и процессы их обработки в логические сущности — объекты, которые имеют способность наследовать характеристики (методы и данные) одного или более объектов, обеспечивая тем самым повторное использование программного кода.
Объектно-ориентированное программирование позволяет разложить проблему на связанные между собой задачи. Каждое событие, таким образом, становится самостоятельным объектом, содержащим свои собственные коды и данные, которые относятся к этому объекту. Реальные объекты окружающего мира обладают тремя базовыми характеристиками: они имеют набор свойств, способны разными методами изменять эти свойства и реагировать на события, возникающие как в окружающем мире, так и внутри самого объекта. Именно в таком виде в языках программирования и реализовано понятие объекта, как совокупности свойств (структур данных, характерных для этого объекта), методов их обработки (подпрограмм изменения свойств) и событий, на которые данный объект может реагировать, и которые приводят, как правило, к изменению свойств объекта.
Исходя из сказанного, каждый объект объединяет как данные, так и программу обработки этих данных и относится к определенному классу. С
173
помощью класса один и тот же программный код можно использовать для относящихся к нему различных объектов.
Механизм наследования - это, пожалуй, самое мощное свойство ООП. Без наследования объекты превращаются в простую комбинацию данных и подпрограмм, не дающую качественных преимуществ по сравнению с традиционными функциями и модулями. Наоборот, механизм наследования позволяет строить библиотеку по принципу "от простого - к сложному". Вводя с помощью наследования новый объект в свою библиотеку, программист в максимальной степени использует уже созданные (и, возможно, отлаженные) ранее объекты. Такой принцип конструирования программ называют восходящим программированием. В отличие от нисходящего программирования, он не дает возможности поэтапного создания программы. Мелкие детали реализации объектов заслоняют собой генеральный алгоритм, поэтому при использовании ООП рекомендуется сочетание подходов.
Какими мощными средствами располагает объектноориентированное программирование наглядно демонстрирует любой более-менее развитый графический интерфейс пользователя. Следует заметить, что преимущества ООП в полной мере проявляются лишь при разработке достаточно сложных программ. Правильно сконструированный объект располагает всеми необходимыми данными и процедурами их обработки, чтобы успешно реализовать требуемые от него действия. Таким образом, ООП в наибольшей степени подходит к задаче разработки библиотек программирования. Попытки использовать ООП для программирования несложных алгоритмических действий, связанных, например, с расчетными вычислениями по готовым формулам, чаще всего выглядят искусственными нагромождениями ненужных языковых конструкций.
Таким образом, объектно-ориентированный подход к проектированию программных продуктов основан на:
выделении классов объектов;
174
установлении характерных свойств объектов и методов их обработки;
создании иерархии классов, наследовании свойств объектов и методов их обработки.
Появление возможности создания объектов в программах
качественно повлияло на производительность труда программистов. Максимальный объем приложений, которые стали доступны для создания группой программистов из 10 человек, за несколько лет увеличился до миллионов строк кода, при этом одновременно удалось добиться высокой надежности программ и, что немаловажно, повторно использовать ранее созданные объекты в других задачах.
6.5. Жизненный цикл программного обеспечения
Бурное развитие вычислительной техники привело к интенсивной математизации не только естественных и технических, но и гуманитарных наук. Все это расширяет круг задач, решаемых на ЭВМ. Реализация на ЭВМ задач каждого класса имеет свою специфику, однако, можно выделить этапы, характерные для большинства задач:
1.Постановка задачи:
сбор информации о задаче;
формулировка условия задачи;
определение конечных целей решения задачи;
определение формы выдачи результатов;
описание данных (их типов, диапазонов величин, структуры и
т.п.).
2. Анализ и исследование задачи, модели:
анализ существующих аналогов;
анализ технических и программных средств;
разработка математической модели;
разработка структур данных.
175
3.Разработка алгоритма:
выбор метода решения задачи;
выбор формы записи алгоритма;
проектирование алгоритма.
4.Программирование:
выбор языка программирования;
уточнение способов организации данных;
запись алгоритма на выбранном языке программирования.
5.Тестирование и отладка:
синтаксическая отладка;отладка семантики и логической структуры;
тестовые расчеты и анализ результатов тестирования;совершенствование программы.
6.Анализ результатов решения задачи и уточнение в случае
необходимости математической модели с повторным выполнением этапов
2 — 5.
7.Сопровождение программы:
доработка программы для решения конкретных задач;
составление документации к решенной задаче, к математической модели, к алгоритму, к программе, к набору тестов, к использованию.
Рассмотрим более подробно каждый из этих этапов.
1. Постановка задачи. На данном этапе формулируется цель решения задачи и подробно описывается ее содержание. Анализируются характер и сущность всех величин, используемых в задаче, определяются условия, при которых она решается. Корректность постановки задачи пользователем является важным моментом, так как от нее в значительной степени зависят все последующие этапы. Ошибки, допущенные на этом этапе, даже при безупречном выполнении последующих этапов могут привести к тому, что разработанный программный продукт не будет соответствовать требованиям практики, сферы его применения. Для
176
создания конкурентоспособных продуктов в ходе выполнения этого этапа должны быть получены четкие ответы на следующие вопросы:
Что должна делать программа?
В чем состоят реальные проблемы, разрешению которых она должна способствовать?
Что представляют собой входные данные?
Какими должны быть выходные данные?
Какими ресурсами располагает проектировщик?
2.На этапе формализации в результате анализа существа задачи определяется объем и специфика исходных данных, вводится система условных обозначений, устанавливается принадлежность решаемой задачи
кодному из известных классов задач и выбирается соответствующий математический аппарат.
Знания о том, как поведет себя система в различных условиях, при различных формах управленческих воздействий специалисты получают путем изучения ее поведения на моделях. Модели позволяют воспроизводить поведение систем в очень широком диапазоне изменяющихся условий, включая такие, которые в реальной действительности трудно наблюдать, или сопряжены с большими затратами и риском. В результате «проигрывания» различных ситуаций оказывается возможным исследовать большое число вариантов развития системы и выбрать наилучший с точки зрения достижения поставленных целей.
Модель – это формальное выражение основных элементов системы в физических или математических терминах.
Математическая модель системы позволяет поставить задачу математически и тем самым свести решение реальной задачи к решению задачи математической. На этом этапе условие задачи описывается либо в виде уравнений или системы уравнений, либо в виде последовательности формул, необходимых для решения задачи. Математическая модель отображает наиболее существенные свойства реального исследуемого
177
объекта или явления, но не тождественна ему, она является лишь приближенным его описанием. Степень соответствия модели реальному объекту проверяется практикой, экспериментом. Эксперимент дает возможность оценить построенную модель и уточнить ее в случае необходимости.
3. Разработка алгоритма начинается с выбора и обоснования численного метода решения задачи. Само по себе математическое описание в большинстве случаев трудно перевести на язык машины. Поэтому необходимо найти способ решения этой задачи. Для некоторых задач существуют точные методы решения, которые предписывают метод вычислений, состоящий в последовательности выполнения арифметических и логических действий. Однако для большинства задач, встречающихся на практике (алгебраические уравнения, системы уравнений, вычисление интегралов, дифференциальные уравнения и т.д.), точные методы решения или неизвестны или дают громоздкие формулы. Для решения этих задач разработаны численные методы, которые обеспечивают приближенное решение широкого класса задач с требуемой точностью. Численные методы решения разработаны практически для любых задач, встречающихся на практике. Если готовых методов для решения поставленной задачи не существует, то их разрабатывают самостоятельно. Если одна и та же задача может быть решена с помощью различных численных методов, то выбирается тот, который удовлетворяет наилучшим образом ее основным требованиям. Обоснованием выбора соответствующего численного метода может быть точность вычислений, время решения задачи на ЭВМ, требуемый объем основной памяти и другие.
После того как численный метод решения задачи выбран, приступают к проектированию алгоритма. Разработка алгоритма заключается в разложении вычислительного процесса на возможные составные части, в установлении порядка их следования, описании
178
содержания каждой такой части в той или иной форме и в последующей проверке: обеспечивается ли реализация выбранного метода.
4. На этапе составления программы алгоритм записывается на языке программирования. Для решения прикладных задач наиболее часто используются алгоритмические языки высокого уровня: Бейсик, Фортран, Паскаль, PL\1 и другие. При разработке программы всю задачу стараются разбить на более простые подзадачи, которые оформляются как самостоятельные процедуры - программные модули. Это облегчает процесс разработки программы, так как, во-первых, решение сложной задачи сводится к решению более простых подзадач, во-вторых, появляется возможность использовать уже готовые программные модули, если какая-то подзадача свелась к уже решенной задаче и, в-третьих, возможен бригадный метод работы над сложной программой, когда каждый разрабатывает собственный программный модуль.
Разработкой программы завершаются этапы реализации задачи, которые выполняются человеком без использования ЭВМ. Все последующие этапы выполняются с ее использованием.
5. Тестирование и отладка программы. Отладка программы — это процесс поиска и устранения ошибок в программе, производимый по результатам её выполнения на компьютере. Тестирование — это испытание, проверка правильности работы программы в целом, либо её составных частей.
Отладка и тестирование — это два четко различимых и непохожих друг на друга этапа: при отладке происходит локализация и устранение синтаксических ошибок и явных ошибок кодирования; в процессе же тестирования проверяется работоспособность программы, не содержащей явных ошибок. Тестирование устанавливает факт наличия ошибок, а отладка выясняет ее причину
В современных системах программирования отладка осуществляется часто с использованием специальных программных средств, называемых
179
отладчиками. Эти средства позволяют исследовать внутреннее поведение программы.
Программа-отладчик обычно обеспечивает следующие возможности:
пошаговое исполнение программы с остановкой после каждой команды (оператора);
просмотр текущего значения любой переменной или нахождение значения любого выражения, в том числе, с использованием стандартных функций; при необходимости можно установить новое значение переменной;
установку в программе "контрольных точек", т.е. точек, в которых программа временно прекращает свое выполнение, так что можно оценить промежуточные результаты, и др.
Как бы ни была тщательно отлажена программа, решающим этапом, устанавливающим ее пригодность для работы, является контроль программы по результатам ее выполнения на системе тестов. Программу условно можно считать правильной, если её выполнение для выбранной системы тестовых исходных данных во всех случаях дает правильные результаты. Но, как справедливо указывал известный теоретик программирования Э. Дейкстра, тестирование может показать лишь наличие ошибок, но не их отсутствие. Нередки случаи, когда новые входные данные вызывают "отказ" или получение неверных результатов работы программы, которая считалась полностью отлаженной.
Тестовые данные должны обеспечить проверку всех возможных условий возникновения ошибок:
должна быть испытана каждая ветвь алгоритма;
очередной тестовый прогон должен контролировать нечто такое, что еще не было проверено на предыдущих прогонах;
первый тест должен быть максимально прост, чтобы проверить, работает ли программа вообще;
арифметические операции в тестах должны предельно упрощаться для уменьшения объема вычислений;
180
количества элементов последовательностей, точность для итерационных вычислений, количество проходов цикла в тестовых примерах должны задаваться из соображений сокращения объема вычислений;
минимизация вычислений не должна снижать надежности
контроля;
тестирование должно быть целенаправленным и систематизированным, так как случайный выбор исходных данных привел бы к трудностям в определении ручным способом ожидаемых результатов; кроме того, при случайном выборе тестовых данных могут оказаться непроверенными многие ситуации;
усложнение тестовых данных должно происходить постепенно. Процесс тестирования можно разделить на три этапа.
1. Проверка в нормальных условиях предполагает тестирование на
основе данных, которые характерны для реальных условий функционирования программы.
2.Проверка в экстремальных условиях. Тестовые данные включают граничные значения области изменения входных переменных, которые должны восприниматься программой как правильные данные. Типичными примерами таких значений являются очень маленькие или очень большие числа и отсутствие данных. Еще один тип экстремальных условий — это граничные объемы данных, когда массивы состоят из слишком малого или слишком большого числа элементов.
3.Проверка в исключительных ситуациях проводится с использованием данных, значения которых лежат за пределами допустимой области изменений. Известно, что все программы разрабатываются в расчете на обработку какого-то ограниченного набора данных. Наихудшая ситуация складывается тогда, когда программа воспринимает неверные данные как правильные и выдает неверный, но правдоподобный результат. Программа должна сама отвергать любые данные, которые она не в состоянии обрабатывать правильно.
181
