Состав объекта
В информатике — композиция объектов и агрегирование объектов это тесно связанные способы объединения объектов или типов данных в более сложные. В разговоре часто игнорируется различие между композицией и агрегацией. [1] Распространенными видами композиций являются объекты, используемые в объектно-ориентированном программировании , теговые объединения , множества , последовательности и различные графовые структуры. Композиции объектов относятся к структурам данных, но не являются ими.
Композиция объекта относится к логической или концептуальной структуре информации, а не к реализации или физической структуре данных , используемой для ее представления. [ нужна ссылка ] . Например, последовательность отличается от набора тем, что (помимо прочего) порядок составленных элементов имеет значение для первого, но не для второго. Структуры данных, такие как массивы , связанные списки , хеш-таблицы и многие другие, могут использоваться для реализации любого из них. Возможно, это сбивает с толку то, что некоторые из одних и тех же терминов используются как для структур данных, так и для композитов. Например, « двоичное дерево » может относиться к любому из двух: как к структуре данных оно представляет собой средство доступа к линейной последовательности элементов, а фактическое положение элементов в дереве не имеет значения (дерево можно внутренне переупорядочить как угодно). не меняя его смысла). Однако в качестве объектной композиции позиции имеют значение, и их изменение приведет к изменению значения (как, например, в кладограммах ). [ нужна ссылка ] .
Техника программирования
[ редактировать ]Объектно-ориентированное программирование основано на объектах для инкапсуляции данных и поведения. Он использует два основных метода сборки и объединения функциональности в более сложные: подтипирование и композицию объектов. [2] Композиция объектов — это объединение объектов внутри составных объектов и в то же время обеспечение инкапсуляции каждого объекта с использованием их четко определенного интерфейса без видимости их внутренних компонентов. В этом отношении композиция объектов отличается от структур данных, которые не требуют инкапсуляции.
Композиция объектов также может представлять собой группу из нескольких связанных объектов, например набор или последовательность объектов. Делегирование может обогатить композицию путем перенаправления запросов или вызовов, сделанных к включающему составному объекту, одному из его внутренних компонентов. [3]
В классовых и типизированных языках программирования типы можно разделить на составные и несоставные типы, а композицию можно рассматривать как связь между типами: объект составного типа (например, автомобиль ) « имеет » объекты других типов ( например, колесо ). Когда составной объект содержит несколько подобъектов одного типа, им могут быть назначены определенные роли , часто отличающиеся именами или номерами. Например, объект Point может содержать три числа, каждое из которых представляет расстояние по разным осям, например «x», «y» и «z». Изучение отношений части и целого в целом является мереологией .
Композицию следует отличать от подтипирования , которое представляет собой процесс добавления деталей к общему типу данных для создания более конкретного типа данных. Например, автомобили могут относиться к определенному типу транспортных средств: car — это транспортное средство . Подтипирование не описывает отношения между различными объектами, а говорит о том, что объекты одного типа одновременно являются объектами другого типа. Изучением таких отношений является онтология .
В языках программирования, основанных на прототипах, таких как JavaScript , объекты могут динамически наследовать поведение объекта-прототипа в момент их создания. Композицию следует отличать от прототипирования: вновь созданный объект наследует композицию своего прототипа, но сам может быть составлен самостоятельно.
Составные объекты могут быть представлены в хранилище путем совместного размещения составных объектов, совместного размещения ссылок или многими другими способами. Элементы составного объекта могут называться атрибутами , полями , членами , свойствами или другими именами, а результирующая композиция — составным типом , записью хранения , структурой , кортежем или определяемым пользователем типом (UDT) . Подробную информацию см. в разделе агрегирования ниже.
Техника UML-моделирования
[ редактировать ]При моделировании UML объекты могут быть концептуально составлены независимо от реализации на языке программирования. В UML существует четыре способа составления объектов: свойство, ассоциация, агрегация и композиция: [4]
- Свойство представляет атрибут класса.
- Ассоциация представляет собой семантическую связь между экземплярами связанных классов. Конец-член ассоциации соответствует свойству связанного класса.
- Агрегация — это своего рода ассоциация, которая моделирует отношения часть/целое между агрегатом (целым) и группой связанных компонентов (частей).
- Композиция, также называемая составной агрегацией, представляет собой своего рода агрегацию, которая моделирует отношения часть/целое между составным элементом (целым) и группой частей, находящихся в исключительном владении.
Связь между агрегатом и его компонентами представляет собой слабую связь «имеет»: компоненты могут быть частью нескольких агрегатов, к ним можно получить доступ через другие объекты, не проходя через агрегат, и они могут пережить агрегатный объект. [4] Состояние объекта-компонента по-прежнему является частью агрегатного объекта. [ нужна ссылка ]
Связь между составным объектом и его частями представляет собой сильную связь «имеет»: составной объект несет исключительную « ответственность за существование и хранение составных объектов », составной объект может быть частью не более чем одного составного объекта, и « При удалении составного объекта все экземпляры его частей, являющиеся объектами, удаляются вместе с ним ». Таким образом, в UML композиция имеет более узкое значение, чем обычная композиция объектов.
Графическое обозначение представляет:
- свойство как типизированный элемент в поле включающего класса,
- ассоциация как простая линия между связанными классами,
- агрегат в виде незаполненного ромба сбоку от агрегата и сплошной линии,
- композиция в виде заполненного ромба сбоку от композита и сплошной линии.
Агрегация
[ редактировать ]Агрегация отличается от обычной композиции тем, что не предполагает владения. В композиции, когда объект-владелец уничтожается, уничтожаются и содержащиеся в нем объекты. В совокупности это не обязательно так. Например, в университете есть различные кафедры (например, химия ), и на каждой кафедре работает несколько профессоров. Если университет закроется, кафедр больше не будет, но профессора на этих кафедрах продолжат существовать. Таким образом, университет можно рассматривать как совокупность кафедр, тогда как кафедры представляют собой совокупность профессоров. Кроме того, профессор мог работать более чем на одной кафедре, но кафедра не могла входить более чем в один университет.
Композиция обычно реализуется таким образом, что один объект содержит другой объект. Например, в С++ :
class Professor; // Defined elsewhere
class Department {
public:
Department(const std::string& title): title_(title) {}
private:
// Aggregation: |Professors| may outlive the |Department|.
std::vector<std::weak_ptr<Professor>> members_;
const std::string title_;
};
class University {
public:
University() = default;
private:
// Composition: |Department|s exist only as long as the faculty exists.
std::vector<Department> faculty_ = {
Department("chemistry"),
Department("physics"),
Department("arts"),
};
};
При агрегировании объект может содержать только ссылку или указатель на объект (и не нести за него пожизненную ответственность).
Иногда агрегацию называют композицией, когда различие между обычной композицией и агрегацией неважно.
Приведенный выше код преобразуется в следующую диаграмму классов UML:
Агрегация в COM
[ редактировать ]Microsoft В объектной модели компонентов агрегация означает, что объект экспортирует, как если бы он был его владельцем, один или несколько интерфейсов другого объекта, которым он владеет. Формально это больше похоже на композицию или инкапсуляцию, чем на агрегацию. Однако вместо реализации экспортированных интерфейсов путем вызова интерфейсов принадлежащего объекта экспортируются сами интерфейсы принадлежащего объекта. Принадлежащий объект отвечает за обеспечение того, чтобы методы этих интерфейсов, унаследованных от IUnknown фактически вызывает соответствующие методы владельца. Это необходимо для того, чтобы гарантировать, что счетчик ссылок владельца правильный и все интерфейсы владельца доступны через экспортированный интерфейс, в то время как другие (частные) интерфейсы принадлежащего объекта недоступны. [5]
Специальные формы
[ редактировать ]Сдерживание
[ редактировать ]Композиция, которая используется для хранения нескольких экземпляров составного типа данных, называется вложением. Примерами таких контейнеров являются массивы , ассоциативные массивы , двоичные деревья и связанные списки .
В UML включение изображается с кратностью 0..* или 1..*, что указывает на то, что составной объект состоит из неизвестного числа экземпляров составного класса.
Рекурсивная композиция
[ редактировать ]Объекты можно составлять рекурсивно, и их тип тогда называется рекурсивным типом . Примеры включают в себя различные виды деревьев , группы DAG и графы . Каждый узел дерева может быть ветвью или листом; другими словами, каждый узел является деревом в то же время, когда он принадлежит другому дереву.
В UML рекурсивная композиция изображается с помощью ассоциации, агрегации или композиции класса с самим собой.
Составной узор
[ редактировать ]Шаблон составного проектирования — это объектно-ориентированный дизайн, основанный на составных типах, который сочетает в себе рекурсивную композицию и включение для реализации сложных иерархий части-целого.
Составные типы в C
[ редактировать ]пример композиции в C. Это
struct Person
{
int age;
char name[20];
enum {job_seeking, professional, non_professional, retired, student} employment;
};
В этом примере примитивные (несоставные) типы интервал , enum {job_seeking, professional,non_professional,пенсионер,студент } и тип составного массива char[] объединяются в составную структуру Человек . Каждый Тогда структура человека «имеет» возраст, имя и тип занятости.
Хронология композиции на разных языках
[ редактировать ]C называет запись структурой или структурой; объектно-ориентированные языки, такие как Java , Smalltalk и C++, часто скрывают свои записи внутри объектов ( экземпляров классов ); языки семейства ML называют их просто записями. COBOL был первым широко распространенным языком программирования , который напрямую поддерживал записи; [6] АЛГОЛ 68 получил его от COBOL, а Паскаль получил его, более или менее косвенно, от АЛГОЛ 68. Common Lisp предоставляет структуры и классы (последние через объектную систему Common Lisp ). [ нужна ссылка ]
- 1959 – КОБОЛ
01 customer-record.
03 customer-number pic 9(8) comp.
03 customer-name.
05 given-names pic x(15).
05 initial-2 pic x.
05 surname pic x(15).
03 customer-address.
05 street.
07 street-name pic x(15).
09 house-number pic 999 comp.
05 city pic x(10).
05 country-code pic x(3).
05 postcode pic x(8).
03 amount-owing pic 9(8) comp.
- 1960 – АЛГОЛ 60
Массивы были единственным составным типом данных в Algol 60 .
- 1964 – ПЛ/И
dcl 1 newtypet based (P); 2 (a, b, c) fixed bin(31), 2 (i, j, k) float, 2 r ptr; allocate newtypet;
- 1968 – АЛГОЛ 68
int max = 99; mode newtypet = [0..9] [0..max]struct ( long real a, b, c, short int i, j, k, ref real r ); newtypet newarrayt = (1, 2, 3, 4, 5, 6, heap real := 7)
Например, связанный список может быть объявлен как:
mode node = union (real, int, compl, string), list = struct (node val, ref list next);
В АЛГОЛе 68 слева от равенства появляется только имя типа, и, что особенно важно, конструкция создается – и ее можно прочитать – слева направо, без учета приоритетов.
- 1970 – Паскаль
type
a = array [1..10] of integer;
b = record
a, b, c: real;
i, j, k: integer;
end;
- 1972 – К&Р С
#define max 99
struct newtypet {
double a, b, c;
float r;
short i, j, k;
} newarrayt[10] [max + 1];
- 1977 – ФОРТРАН 77
В Фортране 77 есть массивы, но отсутствуют какие-либо формальные определения записей/структур. Обычно составные конструкции создавались с использованием ЭКВИВАЛЕНТНОСТЬ или ОБЫЧНЫЕ утверждения:
CHARACTER NAME*32, ADDR*32, PHONE*16
REAL OWING
COMMON /CUST/NAME, ADDR, PHONE, OWING
- 1983 – Ада
type Cust is
record
Name : Name_Type;
Addr : Addr_Type;
Phone : Phone_Type;
Owing : Integer range 1..999999;
end record;
В Ada 95 концепции ООП реализованы через тегированные типы (эквивалент класса C++), в Ada 2012 добавлена поддержка проверки замены посредством общеклассовых контрактов.
- 1983 – С++
const int max = 99;
class {
public:
double a, b, c;
float &r;
short i, j, k;
}newtypet[10] [max + 1];
- 1991 – «Питон»
max = 99
class NewTypeT:
def __init__(self):
self.a = self.b = self.c = 0
self.i = self.j = self.k = 0.0
# Initialise an example array of this class.
newarrayt = [[NewTypeT() for i in range(max + 1)] for j in range(10)]
- 1992 – ФОРТРАН 90
Массивы и строки были унаследованы от FORTRAN 77, и было введено новое зарезервированное слово: type
type newtypet
double precision a, b, c
integer*2 i, j, k
* No pointer type REF REAL R
end type
type (newtypet) t(10, 100)
FORTRAN 90 обновлен и включает FORTRAN IV концепцию под названием NAMELIST.
INTEGER :: jan = 1, feb = 2, mar = 3, apr = 4
NAMELIST / week / jan, feb, mar, apr
- 1994 – ANSI Common Lisp
Common Lisp предоставляет структуры, а стандарт ANSI Common Lisp добавил классы CLOS.
(defclass some-class ()
((f :type float)
(i :type integer)
(a :type (array integer (10)))))
Дополнительные сведения о композиции в C/C++ см. в разделе Составной тип .
См. также
[ редактировать ]- Структура С++
- Составной тип
- Композиция важнее наследования
- Делегирование (программирование)
- Функциональная композиция (информатика)
- Имеет-а
- Наследование реализации
- Семантика наследования
- Закон Деметры
- Объектно-ориентированный анализ и проектирование
- Виртуальное наследование
Ссылки
[ редактировать ]- ^ Ясер, Мишель. «Концепции объектно-ориентированного программирования: композиция и агрегирование» . Архивировано из оригинала 8 апреля 2015 г.
Существует тесно связанное с композицией понятие, называемое агрегацией. В разговоре часто игнорируются различия между композицией и агрегацией.
- ^ Шаблоны проектирования: элементы многоразового объектно-ориентированного программного обеспечения . Гамма, Эрих., Хелм, Ричард (ученый-компьютерщик), Джонсон, Ральф Э., 1955-, Влиссидес, Джон. Ридинг, Массачусетс: Аддисон-Уэсли. 1995. ISBN 0-201-63361-2 . ОСЛК 31171684 .
{{cite book}}
: CS1 maint: другие ( ссылка ) - ^ Остерманн, Клаус; Мезини, Мира (1 октября 2001 г.). «Распутывание объектно-ориентированной композиции» . Уведомления ACM SIGPLAN . 36 (11): 283–299. дои : 10.1145/504311.504303 . ISSN 0362-1340 .
- ^ Перейти обратно: а б ОМГ (2017). «Спецификация унифицированного языка моделирования, версия 2.5.1» . www.omg.org . п. 109-110,197-201 . Проверено 4 октября 2020 г.
- ^ «Агрегация» . Платформенный SDK для Windows XP SP2 . Майкрософт . Проверено 4 ноября 2007 г.
- ^ Себеста, Роберт В. Концепции языков программирования (Третье изд.). Аддисон-Уэсли Паблишинг Компани, Инк. с. 218 . ISBN 0-8053-7133-8 .
Внешние ссылки
[ редактировать ]- Ассоциация, агрегация и состав , по состоянию на февраль 2009 г.
- Харальд Стеррле, UML2, Аддисон-Уэсли, 2005 г.