swift
March 18, 2021

Агрегация vs Композиция

Вместо введения

Решил набросать небольшой пост по ООП... Вот пример композиции и агрегирования с точки зрения кода, написанного на Swift (на Python можно сделать по аналогии). Посмотрев на этот код, вы сможете оценить разницу между ними.

Кстати, в объектно-ориентированном дизайне композиция предпочтительнее наследования, о чем я говорил и в прошлой статье, и даже джавист Джошуа Блох заявлял о её важности в классической книге по Java (Effective Java).

Начать стоит вообще с того, что и агрегация и композиция – это подклассы ассоциации, ну или если можно так выразиться «частные случаи» её проявления. Ассоциация по сути говорит о взаимоотношении с объектом.

Когда мы говорим об ООП, мы всегда думаем об объектах (экземплярах класса), классе (своеобразном «blueprint'е» объектов) и отношениях между ними. Объекты связаны и взаимодействуют друг с другом с помощью методов. Если объект одного класса может использовать методы, предоставляемые объектом другого класса, то такие отношения называются ассоциациями.

Ну ладно, довольно болтологии. Как говорил Линус Торвальдс,

Talk is cheap. Show me the code.

Агрегация

Агрегация, или её ещё называют «слабая ассоциация» – это такой тип отношений, когда у класса есть объект, который он позаимствовал где-то еще (например у другого класса).

Вот например как на картинке выше. Если инстанс (объект) класса Library будет уничтожен, books будет продолжать своё существование, и наоборот.

Если не нравится пример с книгами, вот тут мой любимый пример с машинками и двигателями. Здесь важно понимать главное, «слабая ассоциация» подразумевает, что Car не владеет Engine. Engine создается где-то вовне, и передается внутрь Car. Это и есть агрегация.

машинка делает вжжжж

Композиция

Композиция, или «сильная ассоциация» – это такой тип отношений, когда класс именно «владеет» объектом и несёт ответственность за его время жизни.

Теперь же если инстанс (объект) класса Reader будет уничтожен (деинициализирован), вместе с ним умрёт и books. Как вы уже могли заметить, в этом примере ничего не передается внутрь Reader. Все объекты класса Book создаются внутри самого Reader.

А вот и пример с машинками. Поэтому композиция еще называется «сильной» ассоциацией, в этом случае Car именно «владеет» Engine и ответственен за время жизни его инстанса, если уничтожить инстанс класса Car, пропадет и созданный внутри него инстанс Engine.

Заключение

Грамотный выбор типа отношений между классами и объектами – залог успеха любого ООПшника! Давайте еще раз кратко подытожим все вышесказанное.

  • Агрегация подразумевает такой тип отношений, в которых дочерняя структура может существовать независимо от родительской. Пример: Person (родительский класс) и Student (дочерний класс). Если Person будет удалён, Student всё равно продолжит существовать.
  • Композиция подразумевает такой тип отношений, в которых дочерняя структура не может существовать отдельно от родительской. Пример: House (родительский класс) и Room (дочерний класс). Room не существует отдельно от House.

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


Статья подготовлена для канала Hello World.