Технологии разработки программного обеспечения

Иерархическая организация


Мы рассмотрели три механизма для борьбы со сложностью:

q       абстракцию (она упрощает представление физического объекта);

q       инкапсуляцию (закрывает детали внутреннего представления абстракций);

q       модульность (дает путь группировки логически связанных абстракций).

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

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

Двумя важными инструментами иерархической организации в объектно-ориентированных системах являются:

q       структура из классов («is a»-иерархия);

q       структура из объектов («part of»-иерархия).

Чаще всего «is а»-иерархическая структура строится с помощью наследования. Наследование определяет отношение между классами, где класс разделяет структуру или поведение, определенные в одном другом (единичное наследование) или в нескольких других (множественное наследование) классах.

Пример: положим, что программа управления полетом 2-й ступени ракеты-носителя в основном похожа на программу управления полетом 1-й ступени, но все же отличается от нее. Определим класс управления полетом 2-й ступени, который инкапсулирует ее специализированное поведение:

with Класс_УпрПолетом1; use Класс_УпрПолетом1;

Package Класс_УпрПолетом2 is



type Траектория is (Гибкая. Свободная);

type УпрПолетом2 is new УпрПолетом1 with private;

procedure Установиться: in out УпрПолетом2:

тип: Траектория; ориентация : Углы;

параметры: Координаты_Скорость; команды: График);

procedure УсловияОтделенияЗступени (the: УпрПолетом2;

критерий:КритерийОтделения);

function ПрогнозОтделенияЗступени (the: УпрПолетом2)


return БортовоеВремя;

function ИсполнениеКоманд(the: УпрПолетом2)

return Boolean;

private

type УпрПолетом2 is new УпрПолетом1

              with record

типТраектории: Траектория; доОтделения: БортовоеВремя;

выполнениеКоманд: Boolean;

       end record;

end Класс_УпрПолетом2;

Видим, что класс УпрПолетом2 — это «is а»-разновидность класса УпрПолетом1, который называется родительским классом или суперклассом.

В класс УпрПолетом2 добавлены:

q       авспомогательный тип Траектория;

q       три новых свойства (типТраектории, доОтделения, выполнениеКоманд);

q       три новых метода (УсловияОтделенияЗступени, ПрогнозОтделенияЗступени, ИсполнениеКоманд).

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

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

Иерархию наследования можно продолжить. Например, используя класс УпрПолетом2, можно объявить еще более специализированный подкласс — УпрПолетомКосмическогоАппарата.

Другая разновидность иерархической организации — «part of»-иерархическая структура — базируется на отношении агрегации. Агрегация не является понятием, уникальным для объектно-ориентированных систем. Например, любой язык программирования, разрешающий структуры типа «запись», поддерживает агрегацию.


И все же агрегация особенно полезна в сочетании с наследованием:

1)      агрегация обеспечивает физическую группировку логически связанной структуры;

2)      наследование позволяет легко и многократно использовать эти общие группы в других абстракциях.

Приведем пример класса ИзмерительСУ (измеритель системы управления ЛА):

with Класс_НастройкаДатчиков. Класс_Датчик;

use Класс_НастройкаДатчиков, Класс_Датчик;

Package Класс_ИзмерительСУ is

type ИзмерительСУ is tagged private;

-- описание методов

private

type укз_наДатчик is access all Датчик'Class;

type ИзмерительСУ is record

датчики: array(1..30) of укз_наДатчик;

процедураНастройки: НастройкаДатчиков;

end record;

end Класс_ИзмерительСУ;

Очевидно, что объекты типа ИзмерительСУ являются агрегатами, состоящими из массива датчиков и процедуры настройки. Наша абстракция ИзмерительСУ позволяет использовать в системе управления различные датчики. Изменение датчика не меняет индивидуальности измерителя в целом. Ведь датчики вводятся в агрегат с помощью указателей, а не величин. Таким образом, объект типа ИзмерительСУ и объекты типа Датчик имеют относительную независимость. Например, время жизни измерителя и датчиков независимо друг от друга. Напротив, объект типа НастройкаДатчиков физически включается в объект типа ИзмерительСУ и независимо существовать не может. Отсюда вывод — разрушая объект типа ИзмерительСУ, мы, в свою очередь, разрушаем экземпляр НастройкиДатчиков.

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

 


Содержание раздела