ВУЗ: Университет управления «ТИСБИ»
Категория: Учебное пособие
Дисциплина: Объектно-ориентированное программирование
Добавлен: 20.10.2018
Просмотров: 1153
Скачиваний: 8
4. Разработка простейшего объекта-контейнера
Контейнер – объект, позволяющий хранить и обрабатывать набор
некоторых объектов. Возможные варианты реализации контейнера:
• на основе массива
• на основе динамических списков разных типов
• на основе поисковых деревьев
• на основе хеш-таблиц
Контейнеры полезны сами по себе, но кроме того дают хорошую
практику по освоению объектного подхода. В качестве первого примера
рассмотрим реализацию простейшего контейнера для графических объектов-
окружностей на основе классического массива. В дальнейшем по мере
освоения новых объектных механизмов будут приводиться и другие
варианты реализации контейнеров.
Разработку контейнера будем проводить поэтапно:
неформальное проектирование контейнера
формальное описание в виде класса
программная реализация методов
создание тестовой программы для проверки работоспособности
контейнера
Этап 1. Проектирование контейнера
Для того, чтобы описать контейнер как программный объект,
необходимо определить:
• набор необходимых свойств и их типы
• набор конструкторов и их формальные параметры
• набор необходимых методов доступа
• набор специализированных методов
• форму каждого из методов с точки зрения входных и выходных
параметров
Для
реализации
контейнера-массива
минимально
необходимы
следующие свойства, которые в соответствии с принципом инкапсуляции
необходимо закрыть от постороннего воздействия:
• массив объектных переменных-указателей на окружности
• счетчик текущего количества объектов-окружностей в контейнере
Минимально необходимый набор открытых методов:
• конструктор без параметров для создания пустого контейнера
• Get-метод для свойства-счетчика (а вот Set-метод не нужен, т.к.
изменение счетчика должно происходить только при добавлении или
удалении объектов)
• Get-метод для получения адреса окружности с заданным номером
• метод-функция для добавления нового объекта (для простоты будем
добавлять новый объект только в конец имеющегося набора):
входной параметр – адрес добавляемой окружности
результат – успешность выполнения операции (массив, однако!)
• метод-функция для удаления объекта:
входной параметр – номер удаляемой окружности
результат – адрес удаленного объекта (нулевой в случае неудачи)
• метод-функция поиска объекта:
входной параметр – радиус окружности
результат – номер объекта в массиве и его адрес
• методы-итераторы для циклической обработки объектов в контейнере
(например – показ или перемещение всех окружностей)
Этап 2. Формальное описание в виде класса
Описание контейнерного класса на языке Delphi/Free Pascal
TArrayCircleContainer = class
private
count : integer; // текущее число окружностей в контейнере
Circs : array [1..100] of TCircle; // массив указателей на окружности
public
constructor Create; // создаем пустой контейнер
function GetCount : integer;
function GetCirc (nom : integer) : TCircle; // получение адреса окр-ти
function Add (aCirc : TCircle) : boolean; // добавляем в конец набора
function Delete (ai : integer) : TCircle; // удаление объекта по номеру
function Search (aRad : integer; var Nom : integer) : TCircle; // поиск
procedure ShowAll; // метод-итератор для показа всех окружностей
procedure MoveAll (dx, dy : integer); // еще один итератор
end;
Этап 3. Реализация методов
Далее приводится реализация только некоторых (основных) методов,
тогда как другие (очевидные) оставлены для самостоятельной работы. Кроме
того, данная реализация, как это часто бывает в программировании, является
лишь одной из возможных.
constructor TArrayCircleContainer.Create;
var i : integer;
begin
for i := 1 to 100 do Circs [ i ] := nil; // массив пустых указателей
count := 0;
end;
function TArrayCircleContainer.Add (aCirc : TCircle) : boolean;
begin
result := false; // если добавление будет невозможно
if ( count < 100 ) then
begin
count := count + 1; // а лучше так: inc(count);
Circs [ count ] := aCirc;
result := true; // добавление выполнено
end;
end;
function TArrayCircleContainer.Delete (ai : integer) : TCircle;
begin
result := nil; // если удаление не будет выполнено
if ( count > 0 ) and ( ai <= count ) then
begin
result := Circs [ ai ]; // возвращаем адрес удаляемого объекта
count := count – 1; // а лучше так: dec (count);
«сдвиг хвостовой части массива влево»
end;
end;
function TArrayCircleContainer.Search (aRad : integer; var Nom : integer) :
TCircle;
var i : integer;
begin
result := nil;
if ( count > 0 ) then
for i := 1 to Count do
if ( Circs [ i ].GetR = aRad ) // радиус - через метод доступа
then begin
Nom := i;
result := Circs [ i ];
break;
end;
end;
function TArrayCircleContainer.GetCirc (nom : integer) : TCircle;
begin
result := nil;
if ( count > 0 ) and (nom <= count) then
result := Circs [nom];
end;
procedure TArrayCircleContainer.ShowAll;
var i : integer;
begin
for i := 1 to count do
if ( Circs [ i ] <> nil ) then Circs [ i ].Show;
end;
Этап 4. Демонстрация использования
1. Объявить объектную переменную контейнерного типа:
var MyCont : TArrayCircleContainer;
2. Создать пустой контейнер с помощью конструктора:
MyCont := TArrayCircleContainer.Create;
3. Добавить в контейнер необходимые объекты-окружности за счет
повторения следующих операций:
MyCirc := TCircle.Create(random(…), random(…), random(…));
if MyCont.Add (MyCirc) then «добавили» else «нет места» ;
4. Циклически обработать контейнер:
MyCont.ShowAll;
MyCont.MoveTo (…);
5. Удалить ненужные окружности