Объектно-ориентированных программ

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

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

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

К достоинствам объектно-ориентированного программирова­ния следует отнести:

исключение избыточного кода;

возможность защиты объектов от кода других частей программы;

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

создание более открытых систем;

экономия времени за счет построения программы из готовых, отлаженных частей;

К недостаткам объектно-ориентированного программирования относят:

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

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

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

ТЕСТИРОВАНИЕ, ОТЛАДКА И ОПТИМИЗАЦИЯ ПРОГРАММ

ПРОГРАММНЫЕ ОШИБКИ

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

Входные данные 1%

Ошибки пользователя 5%

Аппаратура 1%

Системное программное обеспечение 3%

Разработка системы 15%

Программирование 75%

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

Существуют два типа программных ошибок:

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

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

ТЕСТИРОВАНИЕ

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

Тестирование программы (program testing) - проверка, которая проводится в ходе прогона программы с целью убедиться, работает ли она так, как требуется. Это осуществляется при выполнении од­ного или нескольких тестовых прогонов, при которых в программ­ную систему подаются входные (тестовые данные), а реакция сис­темы фиксируется для последующего анализа. Может осуществ­ляться как с ЭВМ, так и без ЭВМ.

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

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

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

Статистика свидетельствует, что стоимость тестирования со­ставляет не менее 50% всей стоимости начальной разработки.

Сколько бы сил, времени и денег не было потрачено на тести­рование, один из главных законов программирования действует с неотвратимостью рока: «Тесты могут доказать наличие ошибок в программе, но они не могут доказать их отсутствия» (Э. Дейкстра «Заметки по структурному программированию»).

При тестировании могут возникать следующие вопросы:

1) Искать все ошибки или грубейшие?

2)Если не все, то как установить порог допустимости ошибки?

3)Когда завершать тестирование?

4)Что делать, если сроки поджимают или нет ресурсов на дальнейшее тестирование?

5) Где остановиться в документировании тестов?

Ответы на них во многом зависят от того, что считать качест­венной программой?

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

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

ХОД ТЕСТИРОВАНИЯ

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

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

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

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

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

Наши рекомендации