← Назад к вопросам

Как композиция и агрегация связаны друг с другом?

2.0 Middle🔥 151 комментариев
#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Композиция и агрегация в объектно-ориентированном программировании

Композиция и агрегация — это два типа отношений между объектами в ООП, обе относятся к принципу композиции вместо наследования (Composition over Inheritance). Хотя они похожи, между ними есть важные различия.

1. Основное различие

Агрегация — это отношение типа "часть-целое", где части могут существовать независимо от целого. Композиция — это более строгое отношение, где части не могут существовать отдельно от целого (жизненный цикл привязан).

# АГРЕГАЦИЯ: части существуют независимо
class Company:
    def __init__(self, name, employees):
        self.name = name
        self.employees = employees  # список уже существующих Employee объектов

class Employee:
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary

# Создаем Employee отдельно
employee1 = Employee("Alice", 50000)
employee2 = Employee("Bob", 60000)

# Создаем Company с уже существующими employees
company = Company("TechCorp", [employee1, employee2])

# Employee может существовать без Company
del company
print(employee1.name)  # "Alice" — сотрудник существует!

2. Композиция

В композиции целое отвечает за создание и уничтожение своих частей:

class Engine:
    def __init__(self, horsepower):
        self.horsepower = horsepower
        print(f"Engine created with {horsepower} hp")
    
    def __del__(self):
        print("Engine destroyed")

class Car:
    def __init__(self, brand, horsepower):
        self.brand = brand
        self.engine = Engine(horsepower)  # Car создает Engine
        print(f"Car created")
    
    def __del__(self):
        print("Car destroyed")
        # engine удаляется автоматически при удалении Car

car = Car("BMW", 300)
print("---")
del car  # удаляем машину

# Вывод:
# Engine created with 300 hp
# Car created
# ---
# Car destroyed
# Engine destroyed

3. Агрегация

В агрегации целое содержит ссылки на уже существующие объекты:

class Student:
    def __init__(self, name, student_id):
        self.name = name
        self.student_id = student_id
    
    def __del__(self):
        print(f"Student {self.name} deleted")

class University:
    def __init__(self, name, students):
        self.name = name
        self.students = students  # ссылка на уже существующих студентов
    
    def __del__(self):
        print(f"University {self.name} deleted")

# Студенты существуют независимо
student1 = Student("John", 1001)
student2 = Student("Jane", 1002)

university = University("MIT", [student1, student2])
print("---")
del university  # удаляем университет
print("---")

# Вывод:
# ---
# University MIT deleted
# ---
# Студенты все еще существуют!
print(student1.name)  # John

4. Сравнительная таблица

АспектАгрегацияКомпозиция
Тип отношенияСлабое "часть-целое"Строгое "часть-целое"
Жизненный циклНезависимыйСвязанный
Существование частейМогут существовать отдельноЗависят от целого
ПримерКомпания и сотрудникиАвтомобиль и двигатель
Удаление целогоЧасти остаютсяЧасти удаляются

5. Диаграмма UML

# АГРЕГАЦИЯ (пустой ромб)
Company ◇────── Employee
(целое)          (часть)

# КОМПОЗИЦИЯ (заполненный ромб)
Car ◆────── Engine
(целое)      (часть)

6. Практический пример: Библиотека

class Author:
    def __init__(self, name):
        self.name = name

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author  # агрегация
        print(f"Book {title} created")
    
    def __del__(self):
        print(f"Book {self.title} deleted")

class Library:
    def __init__(self, name):
        self.name = name
        self.books = []  # агрегация книг
    
    def add_book(self, book):
        self.books.append(book)
    
    def __del__(self):
        print(f"Library {self.name} closed")

# Author существует отдельно
author = Author("Tolstoy")

# Book создается с Author (агрегация)
book1 = Book("War and Peace", author)
book2 = Book("Anna Karenina", author)

# Library содержит Books (агрегация)
library = Library("City Library")
library.add_book(book1)
library.add_book(book2)

print("---")
del library
print("---")

# Author и Books все еще существуют!
print(f"{author.name} is still alive")
print(f"Book exists: {book1.title}")

7. Композиция: более строгий пример

class Publisher:
    def __init__(self, name):
        self.name = name

class Page:
    def __init__(self, number, content):
        self.number = number
        self.content = content

class Document:
    def __init__(self, title, publisher):
        self.title = title
        self.publisher = publisher  # агрегация Publisher
        self.pages = []  # композиция Pages
    
    def add_page(self, content):
        page = Page(len(self.pages) + 1, content)  # Document создает Pages
        self.pages.append(page)
    
    def __del__(self):
        print(f"Document {self.title} destroyed")
        # Все pages удаляются с Document

doc = Document("MyBook", Publisher("MyPublisher"))
doc.add_page("Introduction")
doc.add_page("Chapter 1")

print(f"Pages: {len(doc.pages)}")
del doc  # Pages удаляются вместе с Document

8. Когда использовать что

# ✅ Используй АГРЕГАЦИЮ когда:
# - Части могут существовать отдельно
# - Части могут принадлежать нескольким целым
class Team:
    def __init__(self, members):  # members — уже существующие Player объекты
        self.members = members

# ✅ Используй КОМПОЗИЦИЮ когда:
# - Части имеют смысл только как часть целого
# - Целое отвечает за создание/удаление частей
class House:
    def __init__(self):
        self.roof = Roof()  # House создает Roof
        self.walls = [Wall() for _ in range(4)]  # House создает Walls

Ключевые выводы

Композиция — строгое отношение, жизненные циклы привязаны ✅ Агрегация — слабое отношение, независимые жизненные циклы ✅ Композиция "лучше" наследования — используй композицию вместо наследования ✅ DIP — оба паттерна поддерживают принцип инверсии зависимостей ✅ Гибкость — агрегация более гибкая, композиция более надежная

Выбор между ними зависит от семантики вашей предметной области.

Как композиция и агрегация связаны друг с другом? | PrepBro