[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-patterny-chto-takoe-pattern-decorator":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":16,"progress":17,"seo":18},1263,"chto-takoe-pattern-decorator",40,"patterny","Паттерны","🧩","Что такое паттерн Decorator?","Decorator -- паттерн, динамически добавляющий объекту новую функциональность, оборачивая его. Альтернатива наследованию через композицию.\n\n> Аналогия из жизни: Decorator -- как топпинги к кофе. Базовый эспрессо можно \"обернуть\" молоком (латте), сиропом, взбитыми сливками -- каждый слой добавляет что-то новое, не меняя сам кофе.\n\n```java\n\u002F\u002F Классический пример -- java.io\nInputStream raw = new FileInputStream(\"data.txt\");\nInputStream buffered = new BufferedInputStream(raw);           \u002F\u002F декоратор: буферизация\nInputStream gzip = new GZIPInputStream(buffered);              \u002F\u002F декоратор: распаковка\nReader reader = new InputStreamReader(gzip, StandardCharsets.UTF_8); \u002F\u002F декоратор: символьный поток\n```\n\n\u003Cdetails>\n\u003Csummary>Собственный Decorator\u003C\u002Fsummary>\n\n```java\ninterface Logger {\n    void log(String message);\n}\n\nclass ConsoleLogger implements Logger {\n    public void log(String message) { System.out.println(message); }\n}\n\nclass TimestampLogger implements Logger {  \u002F\u002F декоратор\n    private final Logger wrapped;\n    TimestampLogger(Logger wrapped) { this.wrapped = wrapped; }\n\n    public void log(String message) {\n        wrapped.log(\"[\" + Instant.now() + \"] \" + message);\n    }\n}\n\nclass UpperCaseLogger implements Logger {  \u002F\u002F декоратор\n    private final Logger wrapped;\n    UpperCaseLogger(Logger wrapped) { this.wrapped = wrapped; }\n\n    public void log(String message) { wrapped.log(message.toUpperCase()); }\n}\n\n\u002F\u002F Комбинирование декораторов\nLogger logger = new TimestampLogger(new UpperCaseLogger(new ConsoleLogger()));\nlogger.log(\"hello\"); \u002F\u002F [2026-04-22T10:00:00Z] HELLO\n```\n\n\u003C\u002Fdetails>\n\n### Decorator vs Proxy vs Adapter\n\n| Критерий | Decorator | Proxy | Adapter |\n|----------|-----------|-------|---------|\n| Цель | Добавить функциональность | Контролировать доступ | Преобразовать интерфейс |\n| Интерфейс | Тот же, что у обёртки | Тот же, что у обёртки | Другой (целевой) |\n| Пример в JDK | `BufferedInputStream` | `Proxy.newProxyInstance()` | `Arrays.asList()` |\n\n### Частые ошибки\n\n- Слишком глубокая вложенность -- 5+ декораторов усложняют отладку (длинный стек-трейс)\n- Путать Decorator и Proxy -- Decorator добавляет функциональность, Proxy контролирует доступ\n\n### Как используется в 2026\n\n- `java.io` (streams), `Collections.unmodifiable*()`, `Collections.synchronized*()`\n- Spring: `HandlerInterceptor`, `Filter` -- по сути декораторы HTTP-обработки\n\n> **На собеседовании:** назовите java.io как каноничный пример Decorator в JDK -- это покажет понимание стандартной библиотеки. Частая ошибка -- не уметь объяснить разницу между Decorator и Proxy.","","junior",[15],"patterns",[],null,{"title":19,"description":20,"ogTitle":19,"ogDescription":21,"keywords":22,"schemaAnswer":20,"featuredSnippetReady":23},"Что такое паттерн Singleton? — Gymterview","Singleton -- паттерн, гарантирующий, что у класса есть только один экземпляр, и предоставляющий глобальную точку доступа к нему.","Singleton -- паттерн, гарантирующий, что у класса есть только один экземпляр, и предоставляющий глобальную точку доступа",[15,13],true]