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

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

1.0 Junior🔥 241 комментариев
#SOLID и паттерны проектирования#ООП

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

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

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

# Композиция и агрегация в ООП

Введение

Композиция и агрегация — это два способа создания отношений между объектами в объектно-ориентированном программировании. Оба относятся к связи "has-a" (имеет), но имеют разные семантику и жизненные циклы.

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

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

Характеристики агрегации

  1. Жизненный цикл независим
  2. Объект-часть может принадлежать нескольким объектам-целым
  3. При удалении целого, часть может продолжить существовать
  4. Связь слабая, опциональная

Пример агрегации

public class Department {
    private String name;
    private List<Employee> employees;  // Агрегация
    
    public Department(String name) {
        this.name = name;
        this.employees = new ArrayList<>();
    }
    
    public void addEmployee(Employee employee) {
        employees.add(employee);
    }
    
    public void removeEmployee(Employee employee) {
        employees.remove(employee);
    }
}

public class Employee {
    private String name;
    private double salary;
    
    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }
}

// Использование
Employee emp1 = new Employee("John", 50000);
Employee emp2 = new Employee("Jane", 60000);

Department dept = new Department("Engineering");
dept.addEmployee(emp1);
dept.addEmployee(emp2);

// emp1 существует независимо от dept
// Если dept удалена, emp1 всё ещё существует

Важно: работнику не нужно быть частью отдела, чтобы существовать.

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

Композиция — это сильное отношение "has-a", где один объект полностью владеет и управляет жизненным циклом другого объекта.

Характеристики композиции

  1. Жизненный цикл зависим (часть не может существовать без целого)
  2. Сильная связь, обязательная
  3. Объект-часть принадлежит только одному объекту-целому
  4. При удалении целого удаляется и часть
  5. Объект-целое создаёт объект-часть

Пример композиции

public class Person {
    private String name;
    private Brain brain;  // Композиция
    private Heart heart;  // Композиция
    
    public Person(String name) {
        this.name = name;
        this.brain = new Brain();    // Person создаёт объект
        this.heart = new Heart();    // Person создаёт объект
    }
    
    public void think() {
        brain.process();
    }
    
    public void live() {
        heart.beat();
    }
}

public class Brain {
    public void process() {
        System.out.println("Thinking...");
    }
}

public class Heart {
    public void beat() {
        System.out.println("Beating...");
    }
}

// Использование
Person person = new Person("Alice");
person.think();   // Brain используется через Person
person.live();    // Heart используется через Person

// Когда person удалена, brain и heart тоже удаляются

Важно: мозг не может существовать без человека.

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

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

Практические примеры

Агрегация: Team и Player

public class Team {
    private String name;
    private List<Player> players;  // Агрегация
    
    public Team(String name) {
        this.name = name;
        this.players = new ArrayList<>();
    }
    
    public void addPlayer(Player player) {
        players.add(player);
    }
}

public class Player {
    private String name;
    private int number;
    
    public Player(String name, int number) {
        this.name = name;
        this.number = number;
    }
}

// Player может существовать независимо
// Player может быть в разных Team в разные моменты
Player messi = new Player("Messi", 10);
Team barcelona = new Team("Barcelona");
barcelona.addPlayer(messi);

Композиция: Car и Engine

public class Car {
    private String brand;
    private Engine engine;  // Композиция
    private Transmission transmission;  // Композиция
    
    public Car(String brand) {
        this.brand = brand;
        this.engine = new Engine("V8");           // Создаётся внутри
        this.transmission = new Transmission();   // Создаётся внутри
    }
    
    public void start() {
        engine.ignite();
        transmission.engage();
    }
}

public class Engine {
    private String type;
    
    public Engine(String type) {
        this.type = type;
    }
    
    public void ignite() {
        System.out.println("Engine started");
    }
}

public class Transmission {
    public void engage() {
        System.out.println("Transmission engaged");
    }
}

// Engine не может существовать без Car
Car myCar = new Car("Tesla");
myCar.start();

Правило выбора

Используй композицию, если:

  • Объект-часть не имеет смысла без объекта-целого
  • Объект целое полностью контролирует жизненный цикл
  • Это отношение "is-made-of" или "has-a-critical"

Используй агрегацию, если:

  • Объект-часть может существовать независимо
  • Объект-часть может принадлежать нескольким целым
  • Это ослабленное отношение "has-a"

DiSemantика в Java

В Java нет явного синтаксиса для различия композиции и агрегации — это достигается через управление жизненным циклом объектов.

// Композиция: целое создаёт и уничтожает часть
public class Whole {
    private Part part = new Part();  // Создание
    
    // При удалении Whole, Part удаляется автоматически
}

// Агрегация: целое получает часть извне
public class Whole {
    private Part part;  // Внешняя ссылка
    
    public void setPart(Part part) {
        this.part = part;  // Внешнее управление
    }
}

Заключение

Композиция и агрегация — фундаментальные концепции для проектирования объектно-ориентированных систем. Правильный выбор между ними ведёт к более понятному, поддерживаемому и гибкому коду.

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