Связи между объектами

Термины описывают владение и жизненный цикл. Java не проверяет их отдельными ключевыми словами: смысл задаёт модель и код.

СвязьСмыслЖизненный цикл
ассоциацияодин объект знает другойнезависимый
агрегацияслабое «целое — часть»часть живёт отдельно
композициясильное владениечасть создаётся/контролируется владельцем
наследованиеотношение is-aтиповой контракт

Ассоциация

record CustomerId(long value) {}
 
final class Invoice {
    private final CustomerId customerId; // знает клиента по идентификатору
 
    Invoice(CustomerId customerId) {
        this.customerId = customerId;
    }
}

Направление бывает односторонним или двусторонним. Двусторонняя связь требует синхронно обновлять обе стороны и часто усложняет ORM-модель.

Агрегация

final class Team {
    private final List<Employee> members;
 
    Team(List<Employee> members) {
        this.members = List.copyOf(members);
    }
}

Employee существует до и после Team и может участвовать в другой модели. Команда не отвечает за создание сотрудника.

Композиция

final class Order {
    private final List<Line> lines = new ArrayList<>();
 
    void add(Product product, int quantity) {
        lines.add(new Line(product.id(), quantity));
    }
 
    private record Line(ProductId productId, int quantity) {}
}

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

Композиция против наследования

Наследование уместно, когда подтип соблюдает контракт базового типа. Для повторного использования реализации чаще безопаснее композиция: зависимость можно заменить, а наружу не раскрывается весь API родителя.

Ошибки

  • считать любое поле композицией;
  • моделировать is-a только ради повторного использования кода;
  • создавать двусторонние коллекции без методов, поддерживающих обе стороны;
  • путать cascade/orphanRemoval ORM с полным смыслом доменного владения.

На собеседовании

Есть ли в Java оператор агрегации? Нет, это модельное отношение.

Чем композиция сильнее агрегации? Владелец контролирует идентичность и жизненный цикл части.

Почему часто выбирают композицию вместо наследования? Меньше связанность и уже публичный контракт.

Связано: Наследование, Инкапсуляция, Классы Java.