Сохраняемость — это способность абстракции существовать во времени, переживая породивший его процесс, и (или) в пространстве, перемещаясь из своего первоначального адресного пространства.
Любой программный объект существует в памяти и живет в течение некоторого времени. Спектр сохраняемости объектов охватывает:
временные объекты, хранящие промежуточные результаты вычисления выражений;
локальные объекты, существующие внутри подпрограмм, время жизни которых исчисляется от вызова подпрограммы до ее завершения;
глобальные объекты, существующие, пока программа загружена в память;
сохраняемые данные, которые сохраняются в файлах внешней памяти между сеансами выполнения программы.
Композиция и наполнение
В результате объектной декомпозиции второго и далее уровней могут получиться объекты, находящиеся между собой в отношении включения. Классы для реализации таких объектов могут строиться двумя способами: с использованием наследования или композиции.
Наследование применяется тогда, когда разрабатываемый класс имеет с исходным сходную структуру и элементы поведения. В тех случаях, когда сходное поведение не просматривается или наследование по каким-то причинам нецелесообразно, можно использовать композицию классов.
Композицией называется такое отношение между классами, когда один является частью второго. Композиция реализуется включением в класс поля, являющегося объектом другого класса. Такие поля называют объектными.
Включение объектов в некоторый класс можно реализовать и с использованием указателей на объекты, что позволяет включить 0 или более объектов (если они собраны в массив или списковую структуру). Такая реализация класса называется наполнением.
пражнение 1.4.1. Приложение «Бильярд». Спроектируйте классы для написания компьютерной игры в бильярд.
Решение
Для реализации объектов потребуются классы: TBilliardTab-1е (бильярдный стол) и TCircle (шар).
Для описания шаров воспользуемся классом TCircle (упр. 1.3.3), дополнив его новыми характеристиками: color (цвет) и dx, dy — шаг смещения:
Туре
TBall = class (TCircle) private
dx, dy : integer; color: word; public
procedure SetColor(NewColor: word); function GetColor: word;
onstrucror Create(InitX, InitY, InitR, Initdx, Initdy: integer; InitColor: word); end;
Бильярдный стол — это прямоугольник, из которого вырезали по сторонам шесть окружностей (луз). На форме располагаются N окружностей (шаров), образующих первоначальную к онфигурацию:
Туре
TCollection = array[1..100] of TBall; TBilliardTable = class private x, y, width, height: word;
{координаты верхнего левого угла и размеры бильярдного стола}
color: word; {цвет стола}
N: byte; {количество шаров}
Balls: TCollection; {массив указателей на шары}
Pockets: array [1.. б] of TCircle; {массив указателей на лузы} procedure SetConfiguration; abstract;
{начальная расстановка шаров} public
constructor Create(InitX, InitY, InitWidth, InitHeight, NewColor: word; InitN: byte); {конструктор определяет размеры бильярдного стола, расположение луз, вызывает процедуры SetConfiguration и Draw для первоначальной расстановки шаров и изображения стола}
procedure Draw; {изображение бильярдного стола}
procedure Test; {проверка шаров на столкновение шаров между собой и со стенками стола, направление движения шаров при этом изменяется, а также проверка на попадание шаров в лузы}
procedure Solve; {выполняет перемещение шаров,
уменьшая скорость движения шаров; вызывает процедуру Test} destructor Destroy; end;
Таким образом, используя механизм наполнения, в класс TBilliardTable включены объектные поля Balls и Pockets
2.4 Отладка и тестирование программного продукта на уровне модулей
Тестирование и отладка идут рука об руку, так что большинство программистов просто не воспринимают их как отдельные этапы разработки программ. Однако путь к успеху лежит через разделение процесса отладки и тестирования на два разных этапа работы над программой, и вам следует четко представлять себе, что цель тестирования — определить наличие (или отсутствие) ошибок, В то время как цель отладки — определить местоположение ошибок и устранить их. Поскольку цели этих двух этапов разработки программ различны, различны и используемые для этого методы и инструменты. Создание надежного приложения
Лучший путь исключить ошибки в программе — защититься от них еще при написании кода. Надежное приложение — приложение, создаваемое с возможностью легко и просто отлаживать его. Вот основные советы, которые помогут уменьшить количество ошибок при разработке программ.
Приложение должно быть хорошо организовано. Разделите программу на модули, каждый из которых выполняет определенные задачи. Например, если код, создающий отчет, разнесен по десяти модулям, время отладки такого кода увеличится даже более чем в десять раз (хотя бы за счет поиска нужной строки в десяти модулях). Конечно же, вы можете вызывать подпрограммы из других модулей, но они должны быть созданы для выполнения четко поставленной задачи. Неверно размещать одну половину выполняемой операции в процедуре в одном модуле, а вторую половину— в другой процедуре (тем более— в другом модуле). Если процедура не может переварить некорректные данные и вызвать тем самым крах всей системы, проверьте целостность входных данных, прежде чем работать с ними. Однако помните: если системой сможет воспользоваться любой дурак, значит, только дурак и будет ею пользоваться. Не увлекайтесь чрезмерной защитой, которая неумолимо будет отбирать время и ресурсы, необходимые для выполнения более важных задач.
Используйте отладочный вариант вашей программы. В отладочной версии программы содержится дополнительный код, цель которого — отследить выполнение программы, убедиться в корректности ее работы и упростить отладку вашего приложения. Именно об этом и рассказывается в следующем подразделе. Отладочная и коммерческая версии кода. Те, кто участвовали в "полевых испытаниях" (известных как бета-тестрирование) коммерческих программ, наверняка обратили внимание, что такие версии программ более медлительны, гораздо более "разговорчивы" и размером побольше окончательных версий программ. Может быть, разработчик спешил и выпустил "сырой" продукт, который будет улучшать перед выпуском окончательного варианта? Так тоже бывает, но главная причина в другом: в бета-версии содержится тестовый и отладочный коды, используемые разработчиком для проверки корректности работы программы.
Delphi позволяет очень легко внести тестовый и отладочный коды в приложение. Например, вы хотите создать приложение работы с базой данных и использовать быстрый, но, возможно, несколько рискованный алгоритм сортировки данных. Как же убедиться в корректности его работы? Один из путей — использовать в приложении два алгоритма одновременно (быстрый, но рискованный, и медленный, но проверенный), затем сравнить результаты работы обоих алгоритмов. Конечно же, этот вариант используется только в бета-версии, и после всестороннего тестирования, если все работает отлично и без сбоев, в конечной версии продукта останется только быстрый (и после такого тестирования — уже не рискованный) метод сортировки.
Для этого вам вовсе не надо использовать два разных текста программ — воспользуйтесь возможностью условного компилирования. Вы можете определить символ (я обычно использую Debug, но вы свободны в вашем выборе) для переключения между коммерческой и отладочной версиями вашего кода с использованием директив $IFDEF, $IFNDEF, $ELSE и $ENDIF. Вот пример использования "медленного" алгоритма в отладочной версии.
DataSet:= GetData; //Получение данных для сортировки.
{$ifdef Debug}
TestResultSet:= Sort_Tortoise(DataSet); //Медленно и надежно.
{$endif}
ResultSet:= Sort_Hare(DataSet); //Быстро и рискованно.
{$ifdef Debug}
if not CompareData(ResultSet, TestResultSet) then
//Результаты совпали?
Raise Exception. Create('Сортировка в DataSorting некорректна');
{$endif}
Если определен символ Debug, код принимает следующий вид.
DataSet:= GetData; //Получение данных для сортировки.
TestResultSet:= Sort_Tortoise(DataSet); //Медленно и надежно.
ResultSet:= Sort Hare(DataSet); //Быстро и рискованно.
if not CompareData(ResultSet, TestResultSet) then
//Результаты совпали?
Raise Exception. Create('Сортировка в DataSorting некорректна');
Если же символ Debug не определен при создании коммерческого варианта программы, код вырождается в алгоритм быстрой сортировки без дополнительных проверок
DataSet:= GetData; //Получение данных для сортировки.
Re5ultSet:= Sort_Hare(DataSet); //Быстро и рискованно.
Как видите, использование условной компиляции — простои способ создания как отладочной, так и коммерческой версий приложения Вы можете определить символ условной компиляции двумя путями. Первый — глобальное определение символа в опциях проекта. Выберите команду Project/Options и в диалоговом окне Project Options, во вкладке Directories/Conditionals, введите символ в поле Conditional defines. На рис 2.1 показано определение двух символов (Debug и Alpha) Щелкните на кнопке ОК для подтверждения вашего ввода
Изменив символы условной компиляции, перекомпилируйте проект с помощью команды Project/Build All для того, чтобы учесть внесенные изменения.
Другой метод определения символа условной компиляции — вставить в ваш исходный код директиву.
{$define Debug}
Вероятно, вы не захотите возиться с каждым файлом, входящим в проект, и предпочтете определить символ глобально. Однако возможна ситуация, когда, включив символ условной компиляции глобально, вы захотите отключить его в некоторых модулях. Для этого используйте в файле директиву
{$undef Debug}
Она отключает действие директивы Debug до тех пор, пока не встретится соответствующая директива $DEFINE или конец текущего файла. Конечно, вы можете использовать эти директивы сколь угодно часто и в тех местах, где сочтете нужным. Помимо директив условной компиляции, есть еще немало других директив, которые могут использоваться в отладочной версии приложения. Я говорю "могут", поскольку эти директивы могут внести определенные различия в код коммерческой и тестовой версий, так что будьте осторожны при их применении. Эти опции перечислены во вкладке Compiler диалогового окна Project Options, приведенного на рисунке.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |


