Какие преимущества и недостатки у инкапсуляции в ООП?

«Какие преимущества и недостатки у инкапсуляции в ООП?» — вопрос из категории ООП, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Преимущества:

  1. Сокрытие реализации: Внутреннее состояние и логика объекта защищены от прямого внешнего доступа. Клиенты работают через публичный интерфейс (API).
  2. Гибкость и безопасность изменений: Можно менять внутреннюю реализацию класса, не ломая существующий клиентский код, при условии сохранения контракта публичных методов.
  3. Контроль целостности данных: Позволяет добавлять валидацию и бизнес-логику в сеттеры и другие методы, предотвращая попадание объекта в недопустимое состояние.
  4. Упрощение модульного тестирования: Четкие границы объектов и контролируемые зависимости облегчают создание unit-тестов.

Недостатки / Сложности:

  1. Избыточность кода: Для простых классов-контейнеров данных (например, DTO) создание геттеров и сеттеров для каждого поля может быть излишним.
  2. Накладные расходы: Вызов методов доступа (геттеров/сеттеров) теоретически медленнее прямого доступа к полю, хотя современные JVM часто оптимизируют это.
  3. Ложная инкапсуляция: Наличие публичных геттеров и сеттеров для всех полей фактически сводит инкапсуляцию на нет, делая поле доступным для изменения, просто через дополнительный вызов метода.

Пример на Java:

class BankAccount {
    // Поле скрыто (инкапсулировано)
    private double balance;

    // Публичный интерфейс для работы с полем
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount; // Контроль бизнес-правила
        } else {
            throw new IllegalArgumentException("Сумма должна быть положительной");
        }
    }

    // Геттер предоставляет доступ только для чтения
    public double getBalance() {
        return balance;
    }
    // Сеттера для balance нет, что предотвращает произвольное изменение баланса
}