Чем паттерн Proxy отличается от Decorator, если у обоих тот же интерфейс, что и у обёрнутого объекта?
Структурно почти одинаковы, различие — в намерении: декоратор добавляет поведение, и цепочку собирает клиент; прокси управляет доступом к объекту (ленивое создание, права, кэш, удалённость, транзакции) и обычно сам создаёт или получает реальный объект, а клиент о прокси не знает.
- Декораторы: java.io, unmodifiableList
- Прокси: Spring AOP, Hibernate lazy proxy, RMI-заглушки
- Прокси может вообще не вызвать реальный объект (кэш, отказ в доступе)
А ещё На собеседовании ценят признание, что граница размыта
Подробно
Признай сразу, что структурно они почти неразличимы — оба композиция с делегированием и одинаковым интерфейсом, — и переводи разговор на намерение. Декоратор про «и ещё вот это»: клиент сам собирает цепочку обёрток, каждая добавляет аспект — java.io с BufferedInputStream, Collections.unmodifiableList. Прокси про «пущу или не пущу и когда создам»: он контролирует доступ, часто сам создаёт реальный объект лениво, и клиент может о нём не знать — java.lang.reflect.Proxy, ленивые прокси Hibernate, прокси Spring AOP для @Transactional. Заверши практическими следствиями — self-invocation и ограничения CGLIB.
Что хотят услышать
- Намерение каждого.
- Кто собирает обёртку.
- Примеры.
Частые ошибки
- Пытаться развести паттерны по структуре кода вместо намерения.
- Забывать, что у прокси есть разновидности: виртуальный, защитный, удалённый, кэширующий.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Decorator меняет интерфейс объекта, Proxy — нет
- ✓Разница в намерении: декоратор добавляет поведение, прокси управляет доступом
- ✗Proxy всегда вызывает реальный объект, а Decorator может его не вызывать и вернуть данные из кэша
- ✗Proxy бывает только динамическим, создаваемым через рефлексию
Что спросят дальше
- Почему @Transactional не срабатывает при вызове изнутри класса?
- Что общего у прокси с Chain of Responsibility в фильтрах?
Разбор темы
- Структурные паттерны
Adapter, Decorator, Proxy и чем они отличаются друг от друга, Facade, Composite, Bridge и Flyweight — на примерах java.io, java.lang.reflect.Proxy и Spring AOP.
Связанные вопросы
- По какому признаку проще всего отличить Adapter от Decorator и Proxy? Middle
- Какой паттерн лежит в основе конструкции new BufferedInputStream(new GZIPInputStream(new FileInputStream(file)))? Middle
- Spring оборачивает бины в прокси, чтобы работали @Transactional и @Cacheable. Какие практические следствия из этого вытекают? Middle
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.