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

В чем разница между агрегацией и композицией?

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

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

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

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

Разница между агрегацией и композицией

Оба термина описывают виды ассоциаций между объектами в объектно-ориентированном программировании, но с разной силой связи и семантикой владения. Они помогают моделировать отношения "часть-целое".

Ключевое отличие

Основное различие заключается в силе связи и управлении жизненным циклом объектов. Композиция предполагает жёсткую, неразрывную связь, где часть не может существовать без целого, тогда как агрегация — более слабую связь, где часть может жить самостоятельно.

Агрегация (Aggregation)

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

Характеристики:

  • Слабая связь: Объекты-части могут принадлежать нескольким контейнерам одновременно или не принадлежать ни одному.
  • Независимый жизненный цикл: Части создаются и уничтожаются вне контейнера.
  • Передача по ссылке: Контейнер хранит ссылку на объект, который был создан извне.
  • Семантика: Обычно используется для отношений типа "библиотека имеет книги", где книги могут существовать без библиотеки.

Пример на Swift:

class Engine {
    let model: String
    init(model: String) {
        self.model = model
    }
}

class Car {
    let engine: Engine
    
    init(engine: Engine) {
        self.engine = engine // Двигатель передан извне
    }
}

// Двигатель существует независимо от автомобиля
let v8Engine = Engine(model: "V8 Turbo")
let bmw = Car(engine: v8Engine)
let mercedes = Car(engine: v8Engine) // Тот же двигатель может быть в другой машине

// Уничтожение автомобиля не уничтожает двигатель
// (если только нет других ссылок)

Композиция (Composition)

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

Характеристики:

  • Сильная связь: Часть принадлежит исключительно одному контейнеру.
  • Зависимый жизненный цикл: Части создаются и уничтожаются вместе с контейнером.
  • Передача владения: Контейнер полностью отвечает за существование своих частей.
  • Семантика: Используется для отношений типа "человек имеет сердце", где сердце не может функционировать отдельно от человека.

Пример на Swift:

class Heart {
    let beatsPerMinute: Int
    
    init(beatsPerMinute: Int) {
        self.beatsPerMinute = beatsPerMinute
    }
    
    func beat() {
        print("Сердце бьется со скоростью \(beatsPerMinute) уд/мин")
    }
}

class Human {
    private let heart: Heart // Приватное свойство, сильное владение
    
    init() {
        // Сердце создаётся внутри человека
        self.heart = Heart(beatsPerMinute: 72)
    }
    
    func live() {
        heart.beat()
    }
    
    // Когда Human уничтожается, heart также уничтожается
}

let person = Human()
person.live() // Сердце работает только в контексте человека

// Невозможно получить прямой доступ к heart извне класса Human
// Сердце не может существовать отдельно от человека

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

КритерийАгрегацияКомпозиция
СвязьСлабая, "uses-a"Сильная, "owns-a"
Жизненный циклНезависимыйЗависимый
ВладениеРазделяемоеЭксклюзивное
НавигацияОбычно однонаправленнаяЧасто двунаправленная
РеализацияПередача по ссылкеСоздание внутри
ПримерАвтомобиль и двигательДокумент и страницы

Практическое применение в iOS-разработке

Агрегация:

  • UITableViewDataSource — таблица имеет источник данных, но он существует отдельно
  • Делигирование — объект имеет делегата, созданного вне его
  • Сервис-локаторы — объекты получают зависимости извне
// Агрегация в делегировании
protocol PaymentProcessorDelegate: AnyObject {
    func paymentDidComplete()
}

class PaymentProcessor {
    weak var delegate: PaymentProcessorDelegate? // Слабая ссылка
}

Композиция:

  • UIViewController и его view — контроллер владеет корневым view
  • Собственные иерархии view — родительский view владеет дочерними
  • Модели данных — главный объект содержит вложенные структуры
// Композиция в построении UI
class CustomView: UIView {
    private let titleLabel: UILabel
    private let iconImageView: UIImageView
    
    override init(frame: CGRect) {
        // Создаём и настраиваем подкомпоненты внутри
        self.titleLabel = UILabel()
        self.iconImageView = UIImageView()
        
        super.init(frame: frame)
        setupSubviews()
    }
    
    private func setupSubviews() {
        addSubview(titleLabel)
        addSubview(iconImageView)
        // Настройка layout и свойств
    }
}

Заключение

Выбор между агрегацией и композицией зависит от семантики отношений между объектами в вашей доменной модели. Если часть может существовать без целого и/или использоваться несколькими целыми — используйте агрегацию. Если часть является неотъемлемым компонентом, который теряет смысл без целого и имеет одинаковый с ним жизненный цикл — выбирайте композицию.

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

В чем разница между агрегацией и композицией? | PrepBro