Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование


Скачать 1.17 Mb.
Название Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование
страница 4/8
Тип Конспект
rykovodstvo.ru > Руководство эксплуатация > Конспект
1   2   3   4   5   6   7   8

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

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

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

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

Особенности системы, подверженные изменениям, следует скрывать в отдельном модуле. В качестве межмодульных мож­но использовать только те элементы, вероятность изменения которых мала. Все структуры данных должны быть обособлены в модуле; доступ к данным из модуля должен осуществляться только через процедуры данного модуля. Другими словами, следует стремиться построить модули так, чтобы объединить логически связанные абстракции и минимизировать взаимные связи между модулями.

Модульность — это свойство системы, которая была разложена на внутренне связные, но слабо связанные между собой модули.

Правила разделения системы на модули.

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

Многие компиляторы создают отдельный сегмент кода для каждого модуля, поэтому могут появиться ограничения на размер модуля. Динамика вызовов подпрограмм и располо­жение описаний внутри модулей может сильно повлиять на локальность ссылок и управление страницами виртуальной памяти.

Иерархия. Значительное упрощение в понимании сложных задач достигается за счет образования из абстракций иерархи­ческой структуры.

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

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

В ООП используют два вида иерархии.

Иерархия «целое-часть» показывает, что некоторые абст­ракции включены в некоторую абстракцию как ее части, на­пример, строение цветка описывается следующими частями: цветоложе, пестик, тычинки, цветоножка, завязь, лепестки. Этот вариант иерархии используется в процессе разбиения сис­темы на разных этапах проектирования (на логическом уров­не — при декомпозиции предметной области на объекты, на физическом уровне — при декомпозиции системы на модули и при выделении отдельных процессов в мультипроцессорной си­стеме).

Иерархия «общее—частное» — показывает, что некоторая абстракция является частным случаем другой абстракции, на­пример, ель — это разновидность хвойных деревьев, а дере­вья — это часть растительного мира планеты. Используется при разработке структуры классов, когда сложные классы строятся на базе более простых путем добавления к ним новых характеристик и, возможно, уточнения имеющихся.

Разработайте класс Точка.Решение

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

Полная структура класса TPoint имеет вид:



TPosition, указанный в скобках после зарезервированного сло­ва class, сообщает компилятору, что TPoint является «потомком» класса TPosition и соответственно наследует все поля и методы этого класса (в частности, поля Fx и Fy, методы GetX и GetY).

Класс TPoint описывает новые поля, определяющие видимость (FVisible) и цвет (FColor), и методы определить видимость (IsVi­sible), отобразить (Show), спрятать (Hide), переместить (Move).

Конструктор Create и деструктор Destroy переопределяются.

Отметим, что новый класс автоматически получает все дан­ные и методы своих предков, то есть экземпляр класса TPoint содержит все данные (поля) и методы типа TPosition. Таким об­разом, в иерархичном дереве классов по мере удаления от корня будут встречаться все более сложные классы, экземплярами ко­торых будут объекты с более сложной структурой и поведением.

Доступ к полям и методам, описанным в классе-родителе, осуществляется так же, как к собственным.

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

Использование принципа типизации обеспечивает:

раннее обнаружение ошибок, связанных с недопустимыми операциями над программными объектами (ошибки обна­руживаются на этапе компиляции программы при провер­ке допустимости выполнения данной операции над про­граммным объектом);

упрощение документирования;

возможность генерации более эффективного кода.

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

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

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

Совокупность полиморфных методов с одним именем для иерархии классов образует единый полиморфный метод иерар­хии, в котором реализация полиморфного метода для конкрет­ного класса представляет отдельный аспект.

Сложный полиморфизм. Полиморфными объектами, или по­лиморфными переменными, называются переменные, которым в процессе выполнения программы может быть присвоено зна­чение, тип которого отличается от типа переменной.

В языках со строгой типизацией такая ситуация может воз­никнуть

при передаче объекта типа класса-потомка в качестве фак­тического параметра подпрограмме, в которой этот пара­метр описан как параметр типа класса-родителя (явно — в списке параметров или неявно — в качестве внутреннего параметра, используемого при вызове методов — Self);

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

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

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

Рассмотрим это свойство на практике.

Упражнение. Разработайте класс Окружность. Решение

Определим новый класс TCircle (окружность). Окружность определяется центром с координатами х, у и радиусом г. Объ­екты этого типа можно сделать видимыми или невидимыми, задать цвет изображения, переместить и т. д. В связи с этим можно определить новый класс как потомок класса TPoint:

TCircle = class (TPoint)

Private
Fr: Integer; {радиус}

Public

Constructor Create(InitX, InitY, InitR: Integer); Destructor Destroy;

Function GetR: Integer; {возвращает значение радиуса}

Procedure Show; {спрятать}

Procedure Hide; {отобразить}

Procedure Move (NewX, NewY: Integer); {переместить}

End;

Классы TPoint и TCircle связаны отношением наследования и содержат методы Hide (спрятать), Show (отобразить) и Move (переместить). Очевидно, что методы Show и Hide для каждого класса свои, но логика метода Move совпадает:

Переместить:

Спрятать объект; {вызов метода Hide}

Изменить координаты объекта; {x:=NewX; y:=NewY}

Отобразить объект; {вызов метода Show}

Поэтому естественным было бы желание определить метод Move только в TPoint так, чтобы класс-потомок TCircle унасле­довал его без определения. Но в методе Move ссылки на методы Hide и Show формируются на стадии компиляции. Это жест­кая, статическая связь, и без ее «разрыва», т. е. реализации ме­ханизма более позднего формирования ссылок на методы не на стадии компиляции, а на стадии выполнения (динамическое связывание), реализовать это невозможно. Добавление к заго­ловку метода зарезервированного слова virtual объявляет его виртуальным, т. е. связь с этим методом устанавливает на ста­дии выполнения программы. Перепишем описание классов сле­дующим образом:

TPoint = class (TPosition)

Procedure Show; virtual; Procedure Hide; virtual;

end;

TCircle = class (TPoint)

Procedure Show; override; Procedure Hide; override;

end;

Директива override используется для переопределения фун­кциональности метода-предка, она необходима для поддержки полиморфной иерархии.

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

Формирование связи между экземпляром класса (объектом) и ТВМ осуществляет конструктор.

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

Итак, мы смогли исключить метод Move из описания класса TCircle, сделав его полиморфным. Все объекты классов TPoint и TCircle будут использовать его, причем так, как им это необ­ходимо.

Сформулируем правила, которые важно выполнять при ра­боте с виртуальными методами:

если в некотором классе метод описан как виртуальный, то все производные классы, включающие метод с тем же именем, должны описать этот метод как полиморфный (override). Нельзя заменить виртуальный метод статиче­ским;

порядок расположения, количество и типы формальных параметров в одноименных виртуальных методах должны оставаться неизменными.

В дополнении к виртуальным методам, для реализации по­лиморфизма в Object Pascal используются динамические мето­ды. По возможностям наследования и перекрытия они анало­гичны виртуальным методам, но доступ к ним выполняется через таблицу динамических методов (ТДМ). ТДМ хранит адре­са только тех динамических методов, которые определены в данном классе. Такой подход позволяет снизить расход памяти при большом количестве этих методов и самих классов.

На каждый динамический метод приходится только одна ссылка, представленная индексом, по которому и происходит поиск метода для вызова.

Для объявления метода динамическим используется дирек­тива dynamic. Перекрытие динамических методов производит­ся так же, как и виртуальных — с использованием ключевого слова override.

Абстрактные методы

Абстрактные методы используются при объявлении мето­дов, реализация которых откладывается. Такие методы в клас­се описываются служебным словом abstract и обязательно пере­определяются в потомках класса.

Класс, в состав которого входят методы с отложенной реали­зацией, называется абстрактным. Создавать объекты абстракт­ных классов запрещается.

Упражнение 1.3.4. Разработайте родительский класс для ри­сования геометрических фигур.

Решение

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

Скрыть;

Задать новое расположение геометрической фигуры;

Отобразить;

Методы скрыть и отобразить для каждой геометрической фигуры будут определять по-своему, поэтому необходимо объя­вить их виртуальными и абстрактными:

Туре

TPosition = class private

Fx, Fy : integer; public

constructor Create (InitX, InitY: Integer);

function GetX: integer;

function GetY: integer;

destructor Destroy; end;

TGeometricalFigure = class (TPosition) private

Fcolor: word; public

constructor Create(InitX, InitY: integer; InitColor: word);

destructor Destroy;

function GetColor: word;

procedure SetColor(NewColor: word);

procedure Show; virtual; abstract;

procedure Hide; virtual; abstract;

Procedure Move(NewX, NewY: integer); end;

Параллелизм — свойство нескольких абстракций одновре­менно находиться в активном состоянии, т. е. выполнять неко­торые операции.

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

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

Сохраняемость — это способность абстракции существовать во времени, переживая породивший его процесс, и (или) в про­странстве, перемещаясь из своего первоначального адресного пространства.

Любой программный объект существует в памяти и живет в течение некоторого времени. Спектр сохраняемости объектов охватывает:

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

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

глобальные объекты, существующие, пока программа за­гружена в память;

сохраняемые данные, которые сохраняются в файлах внеш­ней памяти между сеансами выполнения программы.

Композиция и наполнение

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

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

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

Включение объектов в некоторый класс можно реализовать и с использованием указателей на объекты, что позволяет вклю­чить 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, приведенного на рисунке.

 



Использование диалогового окна Project Options для определения символов условной компиляции и изменения отладочных опций компилятора

Ниже приведено описание этих опций.

 Optimization. Эта опция управляет оптимизацией компилятора. Рекомендуется оставить эту опцию включенной и выключать ее, если вы полагаете, что оптимизация вносит ошибки в вашу программу. Управлять оптимизацией локально вы можете с помощью директив компилятора $0+ и $0-.

 Stack Frames. Если эта установка включена, компилятор всегда включает в функцию код для генерации кадра стека, даже если код не использует стек. Как и в случае оптимизации, вам вряд ли стоит изменять эту установку. Локальные директивы компилятора— $W-t и $W-.

 Range Checking. Проверка диапазона перехватывает ошибки, вызванные выходом за пределы массива или строки. Однако дополнительный код сдерживает выполнение программы и, по всей видимости, вы отключите эту опцию в коммерческой версии. Директивы компилятора для включения и отключения проверки— $R+ и $R-.

 Assertions (С). Эта опция более полно описана в следующем разделе. Использование данного типа проверок позволяет быстро и просто добавить проверки в код Естественно, в коммерческой версии вы захотите отключить эту возможность. Директивы компилятора— $С+ и $С-.

 Overflow checking (Q). Проверка на переполнение позволяет выяснить, не является ли результат выполнения целочисленной операции слишком большим для размещения его в переменной. Подобно опции Range Checking, данная опция полезна только при отладке, и в коммерческой версии, как правило, отключается. Директивы компилятора— $Q+ и $Q-.
    Отладочная версия вашего кода, вероятно, будет больше по размеру и медленнее коммерческой версии. Поэтому не передайте случайно конечному пользователю отладочную версию!

Использование директивы Assert 
    Оператор Assert— новый оператор в Delphi 4. В действительности это просто тест на логическую истину/ложь. При использовании этого оператора вы убеждаетесь, что логическое выражение истинно, если при выполнении выражение становится ложным, генерируется исключительная ситуация. Синтаксис использования оператора таков:

Assert (<�логическое выражение)

    Можно использовать проверку, например, в начале процедуры для выяснения корректности параметров, как показано ниже.

    procedure Foo(Count: Cardinal); 
    begin 
        Assert(Count < SizeOf(Word)); 
    end.

Модульное тестирование 
    Тема модульного тестирования обширна и многообразна, и писать о ней можно много, но я ограничусь буквально несколькими словами. Кстати, когда речь идет о модульном тестировании, слово модуль не имеет отношения к концепции модулей Delphi и подразумевает функцию, подсистему или другой хорошо определенный программный модуль. 
    Коротко говоря, идея модульного тестирования состоит в разбивке приложения на функциональные единицы и тестировании каждой из них по отдельности. Это часто означает написание одного или нескольких небольших приложений-оболочек, цель создания которых — отработать один из модулей вашего приложения. Ваша задача — выявить все возможные ошибки, так как сообщения о внутренних ошибках программы, допустимые в тестовых версиях, недопустимы в коммерческих. 

Настройка IDE для отладки.   Для работы со встроенным отладчиком Delphi его интегрированная среда разработки (IDE) предлагает целую серию установок, большинство из которых вам лучше не трогать, а оставить, как есть (по умолчанию). Однако если вы все-таки решили изменить установки, выберите команду Tools/Options и в появившемся диалоговом окне Environment Options щелкните на вкладке Preferences.    Ниже перечислены опции вкладки Preferences и их функции.

  • Integrated Debugging. Позволяет включать и отключать встроенный отладчик. Если вы отключите отладчик, отладочные команды в меню Run станут недоступными.




Использование вкладки Preferences для настройки интегрированного отладчика Delphi.

 

  • Step Program Block. Эта опция определяет, должен ли отладчик останавливаться перед началом выполнения основного блока begin. . . end при трассировке программы. Обычно данная опция отключена, и включать ее имеет смысл при добавлении кода в основной блок программы либо при отладке консольного приложения.

  • Hide Designers on Run. Когда эта опция включена, окно Object Inspector и формы, использующиеся при разработке приложения, перед запуском программы на выполнение закрываются. Отключение опции позволяет запускать программу быстрее, но эффект перекрывается используемыми незакрытыми ресурсами приложения. Впрочем, будет ли выбрана эта опция, зависит от пользователя.

  • Break on Exception. При включенной опции IDE всегда перехватывает исключительные ситуации и выводит окно сообщения, даже если в программе исключительная ситуация обрабатывается блоком try. . .except. Включение этой опции упростит отладку, так как выводимые сообщения при этом будут более информативными, чем сообщения обработчика, установленные по умолчанию (сравните рис. 2.6 и 2.7). Помимо этого, IDE размещает окно редактора поверх остальных и выделяет строку, вызвавшую исключительную ситуацию.

 

 

Сообщение об исключительной ситуации при включенной опции Break on Exception

 

Включение в код отладочной информации .
    Перед началом отладки следует убедиться, что в приложение включена отладочная информация Delphi. 
    Для компиляции проекта с отладочной информацией следует выполнить команду Project/Options и в диалоговом окне Project Options выбрать вкладку Compiler.
 



Окно редактора с отладочными значками

 



Вкладка Compiler диалогового окна Project Options

    Включение отладочной информации регулируется следующими установками

  • Debug Information. Опция контролирует включение отладочной информации. При отключении этой опции вы не сможете трассировать код или ставить точки прерывания в любом модуле. Опция эквивалентна директивам компилятора $D и $DEBUGINFO

  • Local Symbols. Опция контролирует включение информации о локальных переменных, декларированных, например, внутри функций, процедур и раздела implementation. Вряд ли у вас возникнет необходимость в отключении этой опции, тем более что она игнорируется при выключенной предыдущей опции. Эквивалентные директивы компилятора— $L и $LOCALSYMBOLS.

  • Symbol Info. Эту опцию нельзя целиком отнести к разряду отладочных, так как ее действие направлено на броузер объектов, а не на встроенный отладчик. Если опция включена, броузер объектов сможет выводить информацию для объектов, определенных в модулях Опция игнорируется при выключенных предыдущих двух опциях Эквивалентные директивы компилятора — $Y и $REFERENCEINFO

    Обычно вы будете включать опции Debug Information и Local Symbols для пошаговой трассировки приложения. Однако, как упоминалось ранее, вы можете отключить отладочную информацию для некоторых модулей (просто используйте соответствующую директиву в начале модуля).

    unit MyUnit; 
    {$D-} 
    interface 
    ...

    Использование директивы $D- автоматически отключает опции Local Symbols и Symbol Info, так что вам не надо отключать их отдельно.

Пошаговая отладка 
    Одна из самых распространенных задач отладки — выполнение программы шаг за шагом, по одной строке за раз для проверки правильности выполнения. При пошаговом прохождении кода отладчик выводит окно редактирования с выполняемой программой. Точка выполнения, показывающая следующую выполняемую строку программы, представляется в виде зеленой стрелки, расположенной слева от области исходного текста в окне редактирования. 
    После успешной компиляции модуля на полосе отладочной информации каждая строка кода, внесшая свой вклад в модуль, будет отмечена маленьким, синим кружком. Если же строка не помечена, значит, здесь поработал оптимизатор. Поскольку для таких строк выполняемый код не сгенерирован эти строки не будут помечены точкой выполнения. 
    Интегрированная среда Delphi предоставляет пользователю несколько команд пошаговой отладки доступных в меню Run (рис 2.10) 
 

 

Используйте меню Run для выполнения команд отладки

    Ниже перечислены команды отладки.

  • Run. Выбор этой команды запускает приложение на выполнение в обычном режиме. Вы можете использовать ее как для запуска приложения, так и для продолжения его работы после какого-либо прерывания выполнения (например, по точке останова). Если включена опция Break on Exception, используйте команду для продолжения работы после получения сообщения об исключительной ситуации

  • Step Over. Когда точка выполнения находится на строке содержащей вызов процедуры или функции, используйте эту команду для выполнения строки, включая вызовы в один шаг, без прохождения отдельных строк вызываемых функций. Точка выполнения перемещается при выполнении на следующую строку

  • Trace Into. В отличие от предыдущей команды, эта опция отработает пошаговую отладку вызываемых процедур и функций. Другими словами, если, например, в строке вызывается некая процедура, то при выполнении этой команды точка выполнения перейдет на первую строку процедуры. Однако если в строке нет таких вызовов, значит, последние две команды идентичны. Будьте осторожны при пошаговой трассировке обработчика события OnPaint. Поскольку при пошаговой отладке окно редактора размещается поверх других окон, требуется перерисовка окна приложения, для чего вызывается обработчик события OnPaint... Вы попадаете в замкнутый круг, точнее— в бесконечный цикл вызовов одного и того же обработчика. Тем не менее, стоит лишь проследить, чтобы окна приложения и редактора не перекрывались, и проблема разрешится сама собой.

  • Trace to Next Source Line. Иногда ваш код вызывает другой код косвенно, например, при вызове функции, которая запускает обработчик события, или при вызове функции Windows API, которая, в свою очередь, запускает функцию косвенного вызова. Поскольку такие вызовы косвенные, отладчик не видит вызова и не отслеживает пошагового выполнения таких вызовов
1   2   3   4   5   6   7   8

Похожие:

Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций междисциплинарного курса мдк. 03. 01 Технология разработки...
Исследовать процессы создания новых технологий и определять их основные тенденции целесообразно, сопоставляя эти технологии с уровнем...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций междисциплинарного курса мдк. 03. 01 Технология разработки...
Исследовать процессы создания новых технологий и определять их основные тенденции целесообразно, сопоставляя эти технологии с уровнем...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Методические рекомендации по выполнению внеаудиторной самостоятельной...
ПМ. 01 Разработка программных модулей программного обеспечения для компьютерных систем
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций
Ш 39 Метрология, стандартизация, сертификация: Конспект лекций / О. А. Шейфель; Кемеровский технологический институт пищевой промышленности....
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций для студентов всех форм обучения специальности 080110...
Налоги и налогообложение: Конспект лекций / Составитель Н. А. Леончик. – Кемерово, 2006. – 80 с
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Календарно-тематический план учебной дисциплины преподаватель Алексеев Александр Игоревич
Наименование междисциплинарного курса мдк. 01. 01 Электрические машины и аппараты
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Технические средства автоматизации конспект лекций
Конспект лекций предназначен для студентов дневной, вечерней, заочной и дистанционной форм обучения по специальности 220301 «Автоматизация...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций мдк 02. 02. Электронные средства и методы геодезических измерений
ПМ. 02. Выполнение топографических съемок, графического и цифрового оформления их результатов
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций Владимир 2010 Министерство образования Российской...
Автоматизированные системы бухгалтерского и управленческого учета. Часть 1: Конспект лекций / Владим гос ун-т; Сост.: Д. Н. Васильев...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций лаконично раскрывает содержание и структуру учебной...
Безопасность жизнедеятельности : конспект лекций для студентов очной и заочной форм обучения / сост. В. М. Домашко; Южный федеральный...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций содержание тема Предмет и задачи курса
Внутренняя и внешняя среда организации (фирмы) и их взаимосвязь. Мировой рынок и его развитие
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Рабочая программа спецкурса Олимпиадное программирование 8 и класс...
Рабочая программа элективного курса «Олимпиадное программирование» для 8 специализированного класса инженерно-технологической направленности...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Рабочая программа междисциплинарного курса мдк 01. 06 «Постановка голоса, хор»
ПО) по программам подготовки специалистов среднего звена (далее – ппссз) по специальности 53. 02. 03 Инструментальное исполнительство...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Рабочая программа междисциплинарного курса «Средства исполнения дизайн-проектов»
Рабочая программа междисциплинарного курса «Средства исполнения дизайн-проектов» разработана на основе Федерального государственного...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций по дисциплине для специальности 080101. 65 «Экономическая безопасность»
Информационные системы в экономике: конспект лекций по дисциплине для обучающихся по специальности 080101. 65 «Экономическая безопасность»...
Конспект лекций междисциплинарного курса мдк 01. 02 Прикладное программирование icon Конспект лекций по дисциплине «Научные основы производства продуктов питания»
Конспект лекций по дисциплине «Научные основы производства продуктов питания» для студентов кафедры «Технология и организация общественного...

Руководство, инструкция по применению




При копировании материала укажите ссылку © 2024
контакты
rykovodstvo.ru
Поиск