Ответ
Преимущества:
- Сокрытие реализации: Внутреннее состояние и логика объекта защищены от прямого внешнего доступа. Клиенты работают через публичный интерфейс (API).
- Гибкость и безопасность изменений: Можно менять внутреннюю реализацию класса, не ломая существующий клиентский код, при условии сохранения контракта публичных методов.
- Контроль целостности данных: Позволяет добавлять валидацию и бизнес-логику в сеттеры и другие методы, предотвращая попадание объекта в недопустимое состояние.
- Упрощение модульного тестирования: Четкие границы объектов и контролируемые зависимости облегчают создание unit-тестов.
Недостатки / Сложности:
- Избыточность кода: Для простых классов-контейнеров данных (например, DTO) создание геттеров и сеттеров для каждого поля может быть излишним.
- Накладные расходы: Вызов методов доступа (геттеров/сеттеров) теоретически медленнее прямого доступа к полю, хотя современные JVM часто оптимизируют это.
- Ложная инкапсуляция: Наличие публичных геттеров и сеттеров для всех полей фактически сводит инкапсуляцию на нет, делая поле доступным для изменения, просто через дополнительный вызов метода.
Пример на 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 нет, что предотвращает произвольное изменение баланса
}