Структурной называют схему, отражающую состав и взаимодействие по управлению частей разрабатываемого программного обеспечения.
Структурные схемы пакетов программ не информативны, поскольку организация программ в пакеты не предусматривает передачи управления между ними. Поэтому структурные схемы разрабатывают для каждой программы пакета, а список программ пакета определяют, анализируя функции, указанные в техническом задании.
Самый простой вид программного обеспечения - программа, которая в качестве структурных компонентов может включать только подпрограммы ибиблиотеки ресурсов. Разработку структурной схемы программы обычно выполняют методом пошаговой детализации.Структурными компонентами программной системы или программного комплекса могут служить программы, подсистемы, базы данных, библиотеки ресурсов и т. п.Структурная схема программного комплекса демонстрирует передачу управления от программы-диспетчера соответствующей программе (рис. 5.1).
Рис. 5.1. Пример структурной схемы программного комплекса
Структурная схема программной системы, как правило, показывает наличие подсистем или других структурных компонентов. В отличие от программного комплекса отдельные части (подсистемы) программной системы интенсивно обмениваются данными между собой и, возможно, с основной программой. Структурная же схема программной системы этого обычно не показывает (рис. 5.2).
Рис. 5.2. Пример структурной схемы программной системы
Более полное представление о проектируемом программном обеспечении с точки зрения взаимодействия его компонентов между собой и с внешней средой дает функциональная схема.
Функциональная схема. Функциональная схема или схема данных (ГОСТ 19.701-90) - схема взаимодействия компонентов программного обеспечения с описанием информационных потоков, состава данных в потоках и указанием используемых файлов и устройств. Для изображения функциональных схем используют специальные обозначения, установленные стандартом. Основные обозначения схем данных по ГОСТ 19.701-90 приведены в табл. 5.1.
Таблица 5.1
Название блока | Обозначение | Назначение блока |
Запоминаемые данные | ![]() | Для обозначения таблиц и других структур данных, которые должны быть сохранены без уточнения типа устройства |
Оперативное запоминающее устройство | ![]() | Для обозначения таблиц и других структур данных, хранящихся в оперативной памяти |
Запоминающее устройство с последовательной выборкой | ![]() | Для обозначения таблиц и других структур данных, хранящихся на устройствах с последовательной выборкой (магнитной ленте и т.п.) |
Запоминающее устройство с прямым доступом | ![]() | Для обозначения таблиц и других структур данных, хранящихся на устройствах с прямымдоступом (дисках) |
Документ | ![]() | Для обозначения таблиц и других структур данных, выводимых на печатающее устройство |
Ручной ввод | ![]() | Для обозначения ручного ввода данных с клавиатуры |
Карта | ![]() | Для обозначения данных на магнитных или перфорированных картах |
Дисплей | ![]() | Для обозначения данных, выводимых на дисплей компьютера |
Функциональные схемы более информативны, чем структурные. На рис. 5.3 для сравнения приведены функциональные схемы программных комплексов и систем.
Все компоненты структурных и функциональных схем должны быть описаны. При структурном подходе особенно тщательно необходимо прорабатывать спецификации межпрограммных интерфейсов, так как от качества их описания зависит количество самых дорогостоящих ошибок. К самым дорогим относятся ошибки, обнаруживаемые при комплексном тестировании, так как для их устранения могут потребоваться серьёзные изменения уже отлаженных текстов.
Рис. 5.3. Примеры функциональных схем: а - комплекс программ; б - программная система
Схемы алгоритмов
Исходя из анализа требований, предъявляемых к системе, определяется набор всех функций, выполнение которых программа должна поддерживать. Далее полученные функции объединяются в логически связанные между собой группы. Каждая из таких групп может стать одним из компонентов программной системы. Надо быть готовым к тому, что первая версия набора компонентов не будет являться полной. В процессе анализа функций и на первых стадиях проектирования архитектуры могут быть выявлены дополнительные функции, которые необходимо включить в разрабатываемую программу. По большей части данные функции будут необходимы для выполнения технологических процессов по поддержанию системы в целостном и работоспособном состоянии. Совершенно естественно предположить, что данные функциональные особенности не могут быть известны заказчику программной системы, и разработчикам на первых этапах разработки.
В первую очередь архитектура программы должна включать общее описание системы. Без такого описания достаточно трудно составить согласованную картину из множества мелких деталей или хотя бы десятка отдельных классов. Архитектура должна включать подтверждения того, что при её разработке были рассмотрены альтернативные варианты, и обосновывать выбор окончательной организации системы.
Архитектура должна чётко определять ответственность каждого компонента. Компонент должен иметь одну область ответственности и как можно меньше знать об областях ответственности других компонентов. Сведя к минимуму объём сведений, известных компонентам о других компонентах, можно легко локализовать информацию о проекте приложения в отдельных компонентах.
Архитектура должна ясно определять правила коммуникации между компонентами программы и описывать, какие другие компоненты данный компонент может использовать непосредственно, какие косвенно, а какие вообще не должен использовать.
Пользовательский интерфейс часто проектируется на этапе выработки требований. Если это не так, его следует определить на этапе разработки архитектуры. Архитектура должна описывать главные элементы формата web-страниц, графического интерфейса (GUI) и т.д. Удобство интерфейса может в итоге определить популярность или провал программы.
Архитектура программы является модульной, чтобы графический интерфейс можно было изменить, не затрагивая основную логику программы.
Программу обработки анкет опроса студентов можно условно разделить на две части с разными функциями и уровнем доступа для пользователей:
Рисунок 2.1. - Структура системы
В данном случае наиболее подходящей является реляционная модель данных, так как вся информация может быть легко представлена в виде таблиц. Реляционная модель данных - логическая модель данных, описывающая структурный аспект, аспект целостности и аспект обработки данных в реляционных базах данных.
Структурный аспект - данные в базе данных представляют собой набор отношений.
Аспект целостности - отношения отвечают определенным условиям целостности.
Аспект обработки - поддерживаются операторы манипулирования отношениями.
Немаловажным аспектом проектирования базы данных является нормализация - процесс преобразования базы данных к виду, отвечающему нормальным формам. Нормализация позволяет обезопасить базу данных от логических и структурных проблем, называемых аномалиями данных. К примеру, когда существует несколько одинаковых записей в таблице, то существует риск нарушения целостности данных при обновлении таблицы. Таблица, прошедшая нормализацию, менее подвержена таким проблемам, т.к. ее структура предполагает определение связей между данными, что исключает необходимость в существовании записей с повторяющейся информацией.
В качестве СУБД была выбрана свободная система управления базами данных MySQL. Гибкость СУБД MySQL обеспечивается поддержкой большого количества типов таблиц: пользователи могут выбрать как таблицы типа MyISAM, поддерживающие полнотекстовый поиск, так и таблицы InnoDB, поддерживающие транзакции на уровне отдельных записей. Благодаря открытой архитектуре и GPL-лицензированию (GNU General Public License - лицензия на свободное программное обеспечение, цель которой предоставить пользователю права копировать, модифицировать и распространять программы, а также гарантировать, что и пользователи всех производных программ получат вышеперечисленные права), в СУБД MySQL постоянно появляются новые типы таблиц.
Важным достоинством СУБД MySQL является то, что она портирована на большое количество платформ, таких как AIX, FreeBSD, HP-UX, GNU/Linux, Mac OS X, NetBSD, OpenBSD, Solaris и Windows. Отметим, что компания MySQL AB предоставляет для свободной загрузки не только исходные коды СУБД, но и откомпилированные и оптимизированные под конкретные операционные системы готовые исполняемые модули.
MySQL имеет интерфейс прикладного программирования (API) для таких языков, как Delphi, C, C++, Java, Perl, PHP, Python и Ruby, библиотеки для языков платформы.NET, а также обеспечивает поддержку для ODBC посредством ODBC-драйвера (Open DataBase Connectivity - это программный интерфейс доступа к базам данных) MyODBC.
Основным типом таблиц был выбран тип MyISAM. MyISAM-таблицы идеально оптимизированы для использования в связке с web-приложениями, где преобладают запросы на чтение. Таблицы типа MyISAM показывают очень хорошие результаты производительности при выборках SELECT. Во многом это связано с отсутствием поддержки транзакций и внешних ключей. Однако при модификации и добавлении записей вся таблица кратковременно блокируется, что может привести к серьёзным задержкам при большой загрузке. Но в случае с программой анализа анкет опроса это не является серьёзной проблемой, так как высокая нагрузка на систему не планируется.
Ещё одним преимуществом таблиц типа MyISAM является платформенная независимость. Табличные файлы можно перемещать между компьютерами разных архитектур и разными операционными системами без всякого преобразования.
В таблицах MyISAM могут быть фиксированные, динамические либо сжатые записи. Выбор между фиксированным и динамическим форматом диктуется определениями столбцов.
Структура базы данных представлена на рисунке 2.4.
Р
исунок 2.3. – Структура базы данных
Таблица it_students содержит данные о студентах, прошедших анкетирование.
Таблица 2.1 – Таблица данных «it_students»
Поле |
Тип |
Длина |
Описание |
id |
Числовой |
11 |
Индекс |
num |
Числовой |
11 |
Номер студенческого билета |
name |
Символьный |
100 |
Имя |
second_name |
Символьный |
100 |
Отчество |
surname |
Символьный |
100 |
Фамилия |
birth |
дата |
- |
Дата рождения |
year_postupl |
год |
- |
Год поступления |
address |
Символьный |
500 |
Адрес |
phone_h |
Символьный |
15 |
Домашний телефон |
phone_m |
Символьный |
15 |
Мобильный телефон |
|
Символьный |
250 |
Адрес e-mail |
icq |
Числовой |
10 |
Номер ICQ |
Таблица it_answers_var содержит варианты ответов на вопросы анкетирования.
Таблица 2.2 – Таблица данных «it_answers_var»
Таблица it_questions содержит вопросы анкетирования.
Таблица 2.3 – Таблица данных «it_questions»
Таблица it_tests_cfg делает привязку вопросов анкетирования к конкретной анкете.
Таблица 2.4 – Таблица данных «it_tests_cfg»
Таблица it_tests содержит данные обо всех анкетах и датах проведения анкетирований.
Таблица 2.5 – Таблица данных «it_tests»
Таблица it_text_answers содержит данные об ответах студентов, вводимых вручную.
Таблица 2.6 – Таблица данных «it_text_answers»
Таблица it_students_answers содержит данные об ответах студентов.
Таблица 2.6 – Таблица данных «it_students_answers»
Примечательно, что для контроллера остаётся скрытым то, с каким типом или реализацией СУБД он работает, все обращения к БД происходят посредствам модели, основной задачей который и является абстрагирование работы с данными. Вместо базы данных можно даже использовать текстовый или XML файл, для контроллера это не будет иметь значения. Параллельно контроллер отправляет запрос компоненту представление, который компонует конечный шаблон и возвращает контроллеру. Так же возможен вариант, когда обмен данными происходит напрямую между моделью и представлением. Контроллер объединяет выборку из базы данных и шаблон представления и передаёт браузеру пользователя.
Рисунок 2.4. - Схема информационных потоков архитектуры МVС
При первом входе студента в систему анкетирования создаётся новый идентификатор сессии. Сессия или session, позволяет серверу определить пользователя с помощью специального номера, который уникален и назначается при работе пользователя с сервером. Кроме того, сессии позволяют связывать переменные с этим пользователем и хранить эти переменные на сервере. Другими словами сессии позволяют делать переменные глобальными для всех компонентов программы. Таким образом, система анкетирования может однозначно определить, от кого из пользователей, работающих с программой, пришли те или иные данные.
Д
алее студент отвечает на ряд вопросов анкетирования и только по окончании опроса все данные сохраняются в базе данных. Алгоритм работы системы анкетирования показан на рисунке 2.5.
Рисунок 2.5. – Алгоритм работы системы анкетирования
Одним из важнейших пунктов безопасности web-приложения является проверка всех поступающих данных, поэтому стоит всегда проверять данные, вводимые пользователем в формы поиска, заполнения полей регистрации и так далее на наличие «опасных» данных. Это может быть вредоносный JavaScript код, PHP или PERL команды, а так же (что самое опасное) - команды серверу.
Следует всегда помнить, что абсолютно любой пользователь – это опасность для незащищенного web-приложения, поэтому всегда стоит проверять запросы и переменные, приходящие от пользователя.
Абсолютно каждая переменная в программе должна на стадии проектирования уже иметь свой тип, будь это число или строка. Особенно остро эта проблема стоит для языков программирования со слабой или отсутствующей типизацией, к которым относятся PHP и JavaScript. Поэтому в наиболее критичных участках программы происходит проверка переменных на соответствие типов.
Особо опасны текстовые переменные, например поле для ввода ответа на вопрос анкеты. Их просто необходимо проверять на наличие вредоносного кода. Для устранения опасности производится удаление некоторых элементов из текста или замена на другие символы. Алгоритм обработки входящих данных в фреймворке CodeIgniter показан на рисунке 2.6.
Р
исунок 2.6. – Алгоритм обработки входящих данных в фреймворке CodeIgniter
2.5 Разработка интерфейса программы
Одним из важнейших вопросов разработки программной системы является разработка пользовательского интерфейса. Любая система, использующая при своем функционировании технические средства, относится к классу систем «человек - машина». Правильно будет выдвинуть следующие требования к интерфейсу систем тестирования:
К
примеру, текстовое поле для ввода даты с использованием jQuery было преобразовано в компактный календарь, обладающий функцией автоматической проверки корректности ввода даты (см. рисунок 2.7).
Рисунок 2.7. – Интерфейс календаря для выбора даты рождения
Пользовательский интерфейс, доступный студентам, проходящим анкетирование, выполнен в некоторой степени минималистично. В результате студенты не отвлекаются на красивую графику и концентрируются на обдумывании ответа на вопрос. Интерфейс с одним из в
опросов показан на рисунке 2.8.
Рисунок 2.8. – Интерфейс ответа на вопрос анкетирования
Рисунок 2.9. - Сообщение об ошибке ввода данных
Система обработки результатов анкетирования может выводить результаты в нескольких режимах – текстовом, графическом и режиме вывода на печать. Интерфейс вывода результатов анкетирования в графическом виде показан на рисунке 2.10.
Рисунок 2.10. – Интерфейс вывода результатов анкетирования
Браузер, который является клиентом по отношению к серверу и посылает ему запрос на обработку Web-страницы, может являться реализацией, так называемых, тонких клиентов. Браузер способен отображать Web-страницы и, как правило, входит в состав операционной системы, а функции его обновления и сопровождения лежат на поставщике операционной системы. Логика приложения сосредотачивается на сервере, а функция браузера заключается в основном в отображении информации, загруженной по сети с сервера, и передаче обратно данных пользователя. Одним из преимуществ такого подхода является тот факт, что клиенты не зависят от конкретной операционной системы пользователя, и Web-приложения, таким образом, являются межплатформенными сервисами.
Существенным преимуществом построения Web-приложений для поддержки стандартных функций браузера заключается в том, что функции должны выполняться независимо от операционной системы данного клиента. Вместо того чтобы писать различные версии для Microsoft Windows, Mac OS X, GNU/Linux и других операционных систем, приложение создается один раз и разворачивается на любой платформе.
Принцип работы web-сервера: известно, что web-серверы хранят информацию в виде текстовых файлов, называемых также страницами. Помимо текста, такие страницы могут содержать ссылки на другие страницы (расположенные на том же самом или другом сервере), ссылки на графические изображения, аудио- и видеоинформацию, различные объекты ввода данных (поля, кнопки, формы и т. д.), а также другие объекты и исполняемые на сервере программы. Фактически страницы представляют собой некоторое связующее звено между объектами различных типов. Их проектируют с применением специального языка разметки гипертекстов HyperText Markup Language, или сокращенно - HTML. Для доступа к информации, расположенной на web-серверах пользователи применяют специальные клиентские программы - браузеры. В настоящее время существуют десятки различных браузеров, но наибольшей популярностью на данный момент пользуются лишь несколько из них:
3.1.2 Пассивные и активные web-серверы
Различают пассивные и активные web-серверы. Если страницы сервера содержат только статическую текстовую и мультимедийную информацию, а также гипертекстовые ссылки на другие страницы, то сервер называется пассивным. Когда же страницы сервера ведут себя аналогично окнам обычных интерактивных приложений, вступая в диалог с пользователем, мы имеем дело с активным сервером.
В настоящее время всё большую популярность набирает использование объектно-ориентированного подхода при разработке web-приложений. И хотя преимущества такого подхода не так очевидны, как, например, в таких языках программирования, как C++ или Java, но всё большее количество свободно распространяемых библиотек и программ, написанных на языке программирования PHP, переходят на объектно-ориентированный интерфейс. Этим они вынуждают использующих их разработчиков обращаться к объектно-ориентированным возможностям PHP. Введение в пятой версии интерпретатора PHP полноценной поддержки объектно-ориентированной модели ещё больше подогревает интерес к этой методологии.
Зачастую использование объектно-ориентированного подхода к месту и не к месту делает проект успешным. Программирование новичка в стиле объектно-ориентированного программирования часто напоминает передвижение по минному полю – если не знать где мины, достичь конца проекта невозможно. Само по себе объектно-ориентированное программирование не является панацеей – это рабочая технология, которая позволяет:
На заре компьютерной эпохи программа представлялаы собой один поток, который обрабатывал один массив данных. Со временем сложность программ и предъявляемых к ним требований возросли, и такой способ организации данных оказался неприемлемым. Был предложен структурный подход, при котором массив данных становился доступен из любой точки программы, однако основной поток программы разбивался на несколько процедур. Отдельную небольшую процедуру, пусть даже использующую общие данные, разрабатывать гораздо проще, чем большой объём исходного кода.
Каждая из процедур обладает локальными переменным, срок жизни которой определяется продолжительностью работы процедуры. Одни процедуры могут вызывать другие, однако массив данных в программе остаётся общим и доступным для всех процедур. Такой подход применяется при процедурном программировании на PHP и позволяет создавать крупные программные комплексы. Но разработка, отладка и поддержка программ, оперирующих большими объёмами данных(как, например, кафедральная БД), всё равно остаётся сложной и требующей значительного мастерства и опыта.
Ответом на всё возрастающую сложность стало появление объектно-ориентированного подхода в программировании: программа разбивается на несколько массивов данных, каждый из которых имеет свои собственные процедуры, а также процедуры, которые взаимодействуют с другими массивами данных.
В результате сложная задача разбивается на ряд более простых подзадач, а разработчики получают более гибкий способ управления проектом – редактировать один огромный монолитный блок кода гораздо сложнее, чем совокупность небольших, слабо связанных между собой блоков.
Независимо от привязки к языку программирования, объектно-ориентированный подход имеет ряд общих принципов, а именно:
3.1.4 Особенности фреймворка CodeIgniter
Используемый фреймворк CodeIgniter написан с использованием объектно-ориентированного подхода. Все классы контроллеров, отображений и моделей, вводимые программистом, наследуют исходные классы, введённые в сам фреймворк. Это даёт возможность писать меньший по объёму исходный код, поскольку все необходимые базовые функции сразу же становятся доступны.
Помимо доступных программисту классов контроллеров, отображений и моделей, в фреймворке CodeIgniter существуют также доступные программисту функции плагинов (plugins) и хелперов (helpers - помощники). Хелперы, как видно из названия, призваны помочь исполнить какую-либо незначительную функцию. Например, существуют хелперы построения web-форм, загрузки файлов или работы с сессиями. В отличие от всех остальных основных элементов фреймворка, хелперы – наборы элементарных функций., написанных даже без использования объектно-ориентированного подхода. Каждая функция выполняет небольшую, строго ограниченную задачу. Однако набор довольно велик, и такая «мелочь» становится очень полезной в работе.
Плагины - почти то же самое, что и помощники, за исключением главного отличия: они не являются набором функций, они и есть одна функция. Кроме этого, можно обратить внимание на то, что помощники - больше часть ядра системы, в то время как плагины - нечто внешнее, разрабатываемое сторонними программистами. В реальности это так и оказывается. Даже те плагины, которые поставляются в основном комплекте, написаны пользователями CodeIgniter, входящими в сообщество.
При разработке программы обработки анкет опроса студентов кафедры также использовался такой важный и полезный инструмент программиста, как интегрированная среда разработки (IDE - Integrated Development Environment), а именно Eclipse. Eclipse - свободный фреймворк для разработки модульных кроссплатформенных приложений. Разрабатывается и поддерживается Eclipse Foundation.
Наиболее известные приложения на основе Eclipse Platform - различные «Eclipse IDE» для разработки ПО на множестве языков (например, наиболее популярный «Java IDE», поддерживавшийся изначально). В данном случае использовались расширения для программирования на языках программирования PHP (модуль PDT) и JavaScript (модуль JSEclipse), а так же вёрстки с использованием языка разметки HTML.
Такой процесс формальной проверки может доказать, что ошибки отсутствуют только с точки зрения используемого метода, но не гарантирует их полное отсутствие.
Тестом называется информация, состоящая из специально подобранных исходных данных, для отлаживаемой программы, и соответствующих им эталонных результатов, используемых для контроля правильности работы программы.
Контроль программы сводится к подбору тестов, получение которыми правильных результатов гарантировало бы правильную работу программы и для остальных исходных данных из всей допустимой области значений.
Тестирование системы проводилось несколькими методами:
Существует множество средства, упрощающих задачу увеличения количества запросов и вызова на сервере множества операций. Тест предельно допустимой нагрузки должен быть спроектирован таким образом, чтобы в точности воспроизводить ожидаемый рабочую нагрузку на приложение.
Для нагрузочного тестирования программы обработки анкет опроса студентов кафедры была использована программа curl-loader. Curl-loader это свободно распространяемая утилита тестирования производительности web-приложений, написанная на языке программирования C. Она способна симулировать сотни и даже тысячи обращений к серверу по протоколам HTTP и HTTPS и использует библиотеку libcurl, что позволяет без каких-либо проблем тестировать приложения, требующие авторизации. А поддержка протокола HTTPS позволяет использовать утилиту curl-loader для нагрузочного тестирования web-приложений, работающих через шифрованные транспортные механизмы SSL (Secure Sockets Layer - уровень защищённых сокетов) и TLS (Transport Layer Security).
При рабочем варианте программы следует, наоборот, отключать параметр display_errors, но включать log_errors. С одной стороны, это усложнит жизнь злоумышленникам, которые уже не смогут увидеть отладочную информацию. С другой стороны, в критической ситуации это поможет вам понять, что именно произошло, и исправить ошибку, даже если она не воспроизводится в тестовом окружении.
В обоих случаях параметр error_reporting удобно выставлять в максимально подробное состояние – E_ALL, заставляющее PHP сообщать о самых незначительных оплошностях в коде.
Учитывая кратковременность выполнения web-приложений и их уровневую конструкцию (клиентское приложение, сеть, web-сервер, прикладной код и применяемая база данных), отловить ошибки в исходном коде может быть нелегко. Даже если предположить, что все уровни, за исключением PHP-кода, работают безупречно, трассировка до обнаружения ошибки в программе может быть трудной, особенно если приложение использует большое количество классов.
Выражение языка PHP echo и такие функции, как var_dump(), debug_zval_dump() и print_r() являются обычными и очень популярными средствами отладки, помогающими решить различные мелкие проблемы. Однако как средства тестирования и отладки эти выражения (и даже более надежный инструментарий, например, пакет PEAR Log) помогают слабо и не всегда.
Кроме того, такая отладка является подходом с позиции "грубой силы". При отсутствии необходимой информации требуется переделывать исходный код, повторять предыдущие действия и начать поиск ошибки заново. Намного более эффективная стратегия - испытывать приложение во время его работы. Можно каталогизировать параметры запроса, просмотреть стек вызовов процедур, узнать значение любой переменной или объекта. Можно временно прервать выполнение приложения и получить уведомление об изменениях значения переменной
Такое "живое" или интерактивное исследование обеспечивается специальным приложением, называемым отладчиком. Отладчик запускает или подключается к процессу для управления им и исследования его памяти. Либо, в случае с интерпретируемыми языками, отладчик может непосредственно интерпретировать код. Типичный современный отладчик может индексировать и просматривать исходный код, отображать сложные структуры данных в читабельном виде и одновременно отображать состояние программы, стек вызовов, выводимые программой данные и значения всех переменных. Например, для отладчика обычным является каталогизация и отображение свойств и методов класса.
Вместо ручного добавления различных функций вывода отладочной информации можно воспользоваться XDebug для создания журнала трассировки. Журнал трассировки это список вызовов функций и методов класса на всем протяжении выполнения программы. Его преимущество заключается в том, что абсолютно каждый вызов найдет свое отражение в журнале.
Журнал трассировки обычно различается от запуска к запуску, так как он зависит от входящих данных, которые различаются от запроса к запросу.
Отслеживание журнала помогает понять, каким образом происходит выполнение программы, однако очень сложно визуализировать все возможные ветвления, если только программа не является очень простой. Именно из-за этого тестирование больших программ достаточно сложно: слишком много различный путей развития и каждый необходимо протестировать.
Средство отладки приложений XDebug, как следует из его названия, предоставляет несколько функциональных возможностей для отображения состояния программы и является очень ценным исследовательским инструментом. Будучи установленным, XDebug вмешивается в процесс для предотвращения бесконечных рекурсий, добавляет в сообщения об ошибках информацию о трассировке стека и функций, следит за распределением памяти, а также выполняет некоторые другие функции. Также Xdebug содержит также набор функций, которые можно добавить в исходный код для получения диагностических данных времени выполнения.
Результаты работы модуля XDebug можно просматривать с помощью программы KCachegrind, позволяющей визуализировать происходящие в исходном коде процессы (см. рисунок 3.1).
Подводя итоги, можно сказать, что XDebug это маленький, но очень полезный инструмент для разработчика PHP, он должен быть установлен на каждый интерпретатор PHP, применяемый для разработки. Но не стоит использовать XDebug на рабочих серверах, так как из-за этого сильно падает производительность.
Р
исунок 2.1. – Интерфейс программы KCachegrind
При отладке и тестировании программы обработки анкет опроса студентов кафедры использовалась система phpUnit, позволяющая производить модульное тестирование web-приложений, написанных на языке программирования PHP.
Для того, чтобы написать минимальный набор тестов, используя phpUnit, необходимо:
Введение в экономическую информатику
Совокупность программ, предназначенная для решения задач на ПК, называется программным обеспечением. Состав программного обеспечения ПК называют программной конфигурацией.
Программное обеспечение, можно условно разделить на три категории:
Рис. 1.
Это программы общего пользования не связаны с конкретным применением ПК и выполняют традиционные функции: планирование и управление задачами, управления вводом-выводом и т.д.
Другими словами, системные программы выполняют различные вспомогательные функции, например, создание копий используемой информации, выдачу справочной информации о компьютере, проверку работоспособности устройств компьютера и т.п.
К системному ПО относятся:
К утилитам относятся:
Необходимо отметить, что часть утилит входит в состав операционной системы, а другая часть функционирует автономно. Большая часть общего (системного) ПО входит в состав ОС. Часть общего ПО входит в состав самого компьютера (часть программ ОС и контролирующих тестов записана в ПЗУ или ППЗУ, установленных на системной плате). Часть общего ПО относится к автономными программам и поставляется отдельно.
Прикладные программы могут использоваться автономно или в составе программных комплексов или пакетов.
Прикладное ПО – программы, непосредственно обеспечивающие выполнение необходимых работ на ПК: редактирование текстовых документов, создание рисунков или картинок, создание электронных таблиц и т.д.
Пакеты прикладных программ – это система программ, которые по сфере применения делятся на проблемно – ориентированные, пакеты общего назначения и интегрированные пакеты. Современные интегрированные пакеты содержат до пяти функциональных компонентов: тестовый и табличный процессор, СУБД, графический редактор, телекоммуникационные средства.
К прикладному ПО, например, относятся:
Инструментальное ПО или системы программирования - это системы для автоматизации разработки новых программ на языке программирования.
В самом общем случае для создания программы на выбранном языке программирования (языке системного программирования) нужно иметь следующие компоненты:
Наиболее популярные редакторы (системы программирования программ с использованием визуальных средств) визуального проектирования:
В понятие структуры программы (program structure) включается состав и описание связей всех модулей, которые реализуют самостоятельные функции программы и описание носителей вводимых и выводимых данных, а также данных, участвующих в обмене между отдельными подпрограммами.
Для разработки больших и сложных программ программисту необходимо овладеть специальными приемами получения рациональной структуры программы, которая обеспечивает почти двукратное сокращение объема программирования и многократное сокращение
Подчиненность модулей программы отражается в схеме иерархии. Однако последняя не отражает порядок их вызова или функционирование программы. Схема иерархии может иметь вид, показанный на рис. 5. Она, обычно, дополняется расшифровкой функций, выполняемой модулями.
Перед составлением схемы иерархии целесообразно составить внешние спецификации программы и составить функциональные описания программы вместе с описанием переменных-носителей данных. Особое внимание следует уделять иерархии типов структурированных данных и их комментированию.
Расчленение программы на подпрограммы производится по принципу от общего к частному, более детальному. Процесс составления функционального описания и составления схемы иерархии является итерационным, а выбор наилучшего варианта является многокритериальным. Расчленение должно обеспечивать удобный порядок ввода частей в эксплуатацию.
Схеме иерархии можно придать любой топологический рисунок. Фрагменты с вертикальными вызовами могут быть преобразованы в вызовы одного уровня посредством введения дополнительного модуля, который может не выполнять никаких полезных функций с точки зрения алгоритма программы. Функция нового модуля может состоять лишь в мониторинге, то есть вызове других модулей в определенном порядке.
Фрагменты с горизонтальными вызовами на одном уровне могут быть преобразованы в вертикальные вызовы модулей разных уровней посредством введения дополнительных переменных, которые не могли быть получены декомпозицией функционального описания на подфункции. Эти дополнительные переменные обычно имеют тип целый или логический и называются флагами, семафорами, ключами событий. Их смысл обычно характеризуется фразой: в зависимости от следующей предыстории действий, выполнить такие-то действия.
В процессе проектирования нужно сделать несколько проектных итераций, каждый раз генерируя новую схему иерархии, и сравнить эти иерархии по данным критериям для отбора лучшего варианта.
Ключ - значение переменной, используемое для подтверждения полномочий на доступ к некоторой информации или подпрограмме.
Флаг - переменная, значение которой свидетельствует о том, что некоторый аппаратный или программный компонент находится в определенном состоянии или что для него выполняется определенное условие. Флаг используется для реализации условного ветвления и прочих процессов принятия решений.
Семафор - тип данных специального назначения, который является средством управления доступом к критическому ресурсу со стороны совместно идущих последовательных процессов.
Над семафором можно производить только две операции (не считая создания и аннулирования): операцию ожидания (занятия) и операцию сигнализации (освобождения). Семафор принимает целое значение, которое не может быть отрицательным. Операция ожидания уменьшает значение семафора на единицу, когда это можно сделать, не получая при этом отрицательного значения, и это означает, что свободный ресурс используется. Операция сигнализации увеличивает значение семафора на единицу, что означает освобождение ресурса.
Критический ресурс - ресурс, который в каждый момент времени используется не более чем одним процессом. Когда требуется, чтобы несколько асинхронных процессов координировали свой доступ к критическому ресурсу, используется управляемый доступ через семафор.
КРИТЕРИИ ОЦЕНКИ КАЧЕСТВА
СТРУКТУРНОЙ СХЕМЫ ПРОГРАММЫ
Первый вариант структурной схемы, полученный путем простого членения функций программы на подфункции с указанием переменных, необходимых для размещения данных, чаще всего не является оптимальным и требуются проектные итерации для улучшения топологии схемы. Эти действия обычно выполняются методом «проб и ошибок». Каждый новый вариант сравнивается с предшествующим по описанным ниже критериям:
1) полнота выполнения специфицированных функций;
2)возможность быстрого и дешевого пополнения новыми, ранее не специфицированными функциями;
3)обозримость (понятность) для проектировщика составных частей программы;
4)максимальная независимость отдельных частей программы;
5) возможность связывания подпрограмм редактором связей;
6)достаточность оперативной памяти;
7) влияние топологии схемы иерархии на скорость выполнения программы при использовании динамической загрузки программы и механизма подкачки страниц;
8) отсутствие разных модулей со сходными функциями. Один и тот же модуль должен вызываться на разных уровнях схемы иерархии;
9)достижение такого графика работы коллектива программистов при реализации программы, который обеспечивает равномерную загрузку коллектива;
10)всемерное сокращение затрат на тестирование программы.
Хорошая схема иерархии в 2-5 раз сокращает затраты на тестирование по сравнению с первоначальным вариантом;
11)использование в данном проекте как можно большего числа проработанных в предшествующих проектах модулей и библиотек при минимальном объеме изготавливаемых заново частей.
Генерация вариантов прекращается при невозможности дальнейших улучшений. Рациональная структура программы обеспечивает сокращение общего объема текстов в 2-3 раза, что соответственно удешевляет создание программы и ее тестирование, на которое обычно приходится не менее 60% от общих затрат. При этом облегчается и снижается стоимость сопровождения программы.
МОДУЛЬНОЕ ПРОГРАММИРОВАНИЕ
Реализация принципа структурного программирования осуществляется с использованием макрокоманд и механизмов вызова подпрограмм. Эти же механизмы подходят и для реализации модульного программирования, которое можно рассматривать как часть структурного подхода.
Необходимо различать использование слова модуль, когда имеется в виду единица дробления большой программы на отдельные блоки (которые могут быть реализованы в виде процедур и функций) и когда имеется ввиду синтаксическая конструкция языков программирования (unit в Object Pascal).
Модульное программирование - это организация программы как совокупности независимых блоков, называемых модулями, структура и поведение которых подчиняются определенным правилам.
Концепцию модульного программирования можно сформулировать в виде нескольких понятий и положений:
1) большие задачи разбиваются на ряд более мелких, функционально самостоятельных подзадач - модулей, которые связаны между собой только по входным и выходным данным;
2) модуль представляет собой «черный ящик» с одним входом и одним выходом. Это позволяет безболезненно производить модернизацию программы в процессе ее эксплуатации, облегчает ее
сопровождение, а также позволяет разрабатывать части программодного проекта на разных языках программирования;
3) в каждом модуле должны осуществляться ясные задачи. Если назначение модуля непонятно, то это означает, что декомпозиция на модули была проведена недостаточно качественно. Процесс декомпозиции нужно продолжать до тех пор, пока не будет ясного понимания назначения всех модулей и их оптимального сочетания;
4) исходный текст модуля должен иметь заголовок и интерфейсную часть, где отражаются назначение модуля и все его внешние связи;
5) в ходе разработки модулей программы следует предусматривать специальные блоки операций, учитывающие реакцию на возможные ошибки в данных или в действиях пользователя.
Большое значение в концепции модульного программирования придается организации управляющих и информационных связей между модулями программы, совместно решающими одну или несколько больших задач.
При работе с модулями нужно помнить их основное отличие от процедур и функций. Традиционные правила сферы действия глобальных и локальных переменных для модулей не работают. Эта языковая конструкция разработана так, чтобы исключить влияние глобальных переменных, объявленных в главной программе, на внутренние описания модуля. Поэтому, если возникает необходимость ввести доступные для всех блоков программы глобальные описания то следует создать модуль глобальных объявлений и включить его в список импорта всех модулей, где нужны его описания.
3.7. СТРУКТУРА МОДУЛЯ В OBJECT PASCAL
Object Pascal имеет различные средства для структурирования программ. На нижнем уровне деления (для элементарных подзадач) чаще всего используются процедуры и функции, а на верхнем уровне (для больших задач) используются модули.
В среде Delphi каждой форме обязательно соответствует свой модуль, что позволяет локализовать все свойства окна в отдельной программной единице. Кроме этого, невизуальные алгоритмические действия также оформляются в виде отдельных модулей. Первая строка модуля начинается с ключевого слова:
unit <идентификатор_модуля>;
Для правильной работы среды программирования это имя должно совпадать с именем дискового файла, в который помещается исходный текст модуля. Далее следует
{Интерфейсный раздел} interface
где описывается взаимодействие данного модуля с другими пользовательскими и стандартными модулями, а также с главной программой.
Связь модуля с другими модулями устанавливается специальным предложением:
{Список импорта интерфейсного раздела} uses <список_модулей>
В этом списке через запятые перечисляются идентификаторы модулей, информация интерфейсных частей которых должна быть доступна в данном модуле.
{Список экспорта интерфейсного раздела} const type var
procedure function
Список экспорта состоит из подразделов описания констант, типов, переменных, заголовков процедур и функций, которые определены в данном модуле, но использовать которые разрешено во всех других модулях и программах, включающих имя данного модуля в своей строке uses. Для процедур и функций здесь описываются только заголовки, но с обязательным полным описанием формальных параметров.
{Раздел реализации) implementation
В этом разделе указывается реализационная (личная) часть описаний данного модуля, которая недоступна для других модулей и программ.
{Список импорта раздела реализации) uses
В этом списке через запятые перечисляются идентификаторы модулей, информация интерфейсных частей которых должна быть доступна в данном модуле. Здесь целесообразно описывать идентификаторы всех необходимых модулей, информация из которых не используется в описаниях раздела interface данного модуля.
{Подразделы внутренних для модуля описаний} label const type var
procedure function
В этих подразделах описываются метки, константы, типы, переменные, процедуры и функции, которые описывают алгоритмические действия, выполняемые данным модулем, и которые являются «личной собственностью» исключительно только данного модуля. Эти описания недоступны ни одному другому модулю.
Исполняемая часть содержит описания подпрограмм, объявленных в интерфейсной части. Описанию подпрограммы должен предшествовать заголовок, в котором можно опускать список формальных параметров и тип результата для функции. Если заголовки указаны с параметрами, то их список должен быть идентичен такому же списку для соответствующей процедуры или функции в разделе interface.
{Раздел инициализации} initialization
В этом разделе между ключевыми словами initialization и finalization располагаются операторы начальных установок, необходимых для запуска корректной работы модуля. Эти операторы исполняются до передачи управления основной программе и обычно используются для подготовки ее работы. Операторы разделов инициализации модулей, используемых в программе, выполняются при начальном запуске программы в том же порядке, в каком идентификаторы модулей описаны в предложениях uses файла проекта. Если операторы инициализации не требуются, то зарезервированное слово initialization может быть опущено.
{Раздел завершения) finalization
Раздел завершения finalization является необязательным и может присутствовать только вместе с разделом инициализации initialization. В разделе завершения располагается список операторов, которые будут выполняться при завершении модуля, что обычно происходит при окончании работы приложения. Разделы finalization модулей приложения выполняются в порядке, противоположном выполнению разделов initialization этих модулей.
Раздел завершения используется, как правило, для освобождения ресурсов, которые выделяются приложению в разделе инициализации. Это гарантирует корректное завершение приложения, что особенно это важно, когда приложение заканчивается по возникновению исключительных ситуаций.