Файл: 5. Взаимодействие объектов. Агрегация и композиция.pdf

Добавлен: 20.10.2018

Просмотров: 1569

Скачиваний: 9

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

 

 

5. Взаимодействие объектов: агрегация и композиция

 

Как  уже  было  отмечено,  объектная  программа  –  это  набор 

взаимодействующих  объектов  разных  классов,  совместно  реализующих 

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

классов  вряд  ли  принесет  ощутимый  результат.  Объектный  подход  –  это 

средство  борьбы  со  сложностью  создаваемых  программных  систем,  в 

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

различными способами.  

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

причем отражением этих взаимодействий на формальном уровне являются 

отношения  между  соответствующими  классами.  Поэтому  построение 

объектной  модели  –  это  выделение  необходимых  классов  и  установление 

между ними определенных отношений.  

Пожалуй,  наиболее  понятным  способом  взаимодействия  объектов 

является  случай,  когда  один  объект  включает  в  себя  в  качестве 

составляющих  частей  объекты  других  классов.  В  этом  случае  между 

классами  устанавливается отношение  типа  “часть-целое”.  В оригинальной 

англоязычной  литературе  такое  отношение  описывается  термином  “has-a” 

(имеет,  содержит,  включает  в  себя).  В  теории  ООП  такой  тип  отношения 

называют агрегацией. При этом различают строгую и нестрогую агрегацию. 

Нестрогая  агрегация  –  это  такое  взаимодействие  объектов,  при  котором 

составной объект и образующие его части могут существовать  независимо 

и  отдельно  друг  от  друга.  Строгая  агрегация  или  композиция  возникает 

тогда,  когда  существование  составного  объекта  зависит  от  существования 

входящих в него частей.  

Очень  важно  понимать,  что  отношение  агрегации/композиции  можно 

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

следует  начинать,  это  выяснение  возможности  установления  подобной 

связи.  


background image

 

 

Предположим, имеются два объекта А и B разных классов. Между ними 

можно  установить  отношение  агрегации,  если  утверждение  «Объект  A 

можно  рассматривать  как  составную  часть  объекта  B»  не  противоречит 

здравому смыслу. 

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

1. Объект «Компьютер» можно рассматривать как набор более простых 

объектов,  таких  как  «Основная  (материнская)  плата»,  «Монитор», 

«Жесткий  диск»,  «Мышь»,  «Клавиатура».  В  свою  очередь,  объект 

«Основная  плата»  можно  рассматривать  состоящим  из  более  простых 

объектов типа «Процессор», «Основная память» и др. 

2. Геометрический объект «Окружность» может включать в себя более 

простой объект «Точка» для хранения координат своего центра; аналогично 

объект «Прямоугольник» может состоять из двух объектов-точек, которые 

задают координаты двух его противоположных углов. Более того, составной 

объект  «Деталь»  можно  разложить  (декомпозировать)  на  отдельные 

составляющие – объекты «Окружность», «Отрезок», «Прямоугольник» и 

т.д.  

3. Объект «Оконное приложение» содержит хотя бы один объект типа 

«Оконная форма», который в свою очередь может включать такие объекты 

как «Кнопка», «Поле ввода», «Список», «Таблица», «Переключатель» и 

т.д. 

4.  Объект  «Контейнер-массив  динамических  списков»  состоит  из 

отдельных  объектов  типа  «Динамический  список»,  каждый  из  которых  в 

свою очередь состоит из объектов типа «Элемент динамического списка». 

 

С  другой  стороны  –  контрпример:  объект  «Стул»  вряд  ли  стоит 

рассматривать как часть объекта «Стол» и поэтому эти объекты не следует 

связывать отношением агрегации/композиции.  

Необходимо отметить, что с течением времени связи между объектами 

могут  меняться,  что  является  отражением  изменения  самой  объектной 


background image

 

 

модели,  вызванное изменением  исходных  объектов.  Например, если  лет 20 

назад  утверждение  «Компьютер  можно  рассматривать  как  ЧАСТЬ 

автомобиля»  противоречило  общепринятым  понятиям,  то  в  настоящее 

время оно вполне имеет право на существование. 

Следующим  шагом  после  выяснения  возможности  использования 

композиционной  связи  является  разработка  необходимых  классов

Очевидно,  что  в  любой  объектной  информационной  модели  будет 

существовать    некоторый  набор  классов,  которые  описывают  неделимые 

объекты,  т.е.  объекты,  не  содержащие  других  объектов.  Такие  классы 

объявляются обычным стандартным образом. А вот классы для составных 

объектов имеют некоторые особенности описания. 

Прежде всего, в состав свойств таких классов должны быть включены 

свойства  объектного  типа  или  другими  словами  –  переменные 

соответствующих классовых типов. Поскольку такие переменные являются 

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

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

Пример  фрагмента  описания  составного  класса    ComboClass    с 

использованием  объектных  свойств  классовых  типов  SimpleClass1  и   

SimpleClass2: 

class = ComboClass 

   subObject1 : SimpleClass1; 

   subObject2 : SimpleClass2; 

   // обычные свойства 

   . . . . . . . . . . 

end

ComboClass  class  { 

   SimpleClass1   subObject1; 

   SimpleClass2   subObject2; 

   // обычные свойства 

   . . . . . . . . . . 

};

 

 

Схематично  связь  составного  объекта  с  его  объектами-частями  можно 

представить следующим образом:

 

 

 

свойство 1 
свойство 2

 

 

составной объект 
класса  ComboClass

 

простой объект класса SimpleClass1   

 


background image

 

 

 

 

 

 

 

 

 

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

объекту следующие возможности: 

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

объектов (как правило – через методы доступа)  

  вызывать  открытые  методы  связанных  объектов,  т.е.  использовать 

ранее созданный программный код 

В  целом,  механизм  агрегации/композиции  позволяет  конструировать 

сложные  объекты  на  основе  ранее  созданных  объектов,  постепенно 

наращивая уровень сложности.  

В  качестве  примера  можно  привести  два  варианта  описания  класса 

объектов  «Компьютер».  В  первом  варианте  для  хранения  информации  о 

процессоре и основной памяти используются строковые поля: 

TComputer = class 

   cpu : string

   memory : string

   . . . . . . . . . 

end; 

Computer  class   

{   string   cpu; 

     string   memory; 

      . . . . . . . . . . 

}; 

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

процессоре  и  памяти  надо  иметь  более  подробную  информацию, 

целесообразно  ввести  отдельные  (самостоятельные)  классы  для  объектов 

«Процессор»  и  «Память»,  а  в  классе  «Компьютер»  использовать  механизм 

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

объектное свойство  
subObject1 
объектное свойство 
subObject2 
обычные свойства 
. . . . . . . . . .

 

 

свойство 1 
свойство 2

 

 

простой объект класса SimpleClass2   

 


background image

 

 

TCPU =  class 

// поля и методы класса «Процессор» 

 

TMem =  class 

// поля и методы класса  «Память» 

 

TComputer = class

 

 

 

      cpu : TCPU;  // связующее поле 

      mem : TMem; // связующее поле 
// другие поля 
// методы 

 class   CPU 

// поля и методы класса «Процессор» 

 

 class   Memory 

// поля и методы класса  «Память» 

 

 class    Computer

 

 

     CPU    cpu;   // связующее поле 

     Memory   mem;  // связующее поле 
// другие поля 
// методы

 

 

При  разработке  составных  классов  обязательно  надо  продумать 

механизм  создания  объектов  таких  классов.  При  этом  возможны  два 

основных варианта реализации конструкторов в составных классах. 

1.  Конструктор  составного  класса  должен  создать  все  необходимые 

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

классов,  при  необходимости  передавая  им  входные  параметры  и 

устанавливая  значение  связующих  объектных  переменных  в  адреса 

созданных  этими  конструкторами  объектов.  Пример  для  составного  класса 

«Компьютер»: 

constructor  TComputer.Create (входные параметры); 

begin 

   cpu := TCPU.Create (…);   // установка связи с создаваемым объектом 

   mem := TMem.Create (…); // установка связи с создаваемым объектом 

   // установка обычных свойств 

end; 

public  Computer (входные параметры)  { 

   cpu =  new  CPU (…);        // установка связи с создаваемым объектом 

   mem =  new  Memory (…); // установка связи с создаваемым объектом 

   // установка обычных свойств