Ответ
Паттерн Декоратор (Decorator) динамически добавляет объекту новые обязанности, предоставляя гибкую альтернативу наследованию для расширения функциональности.
Пример: Добавление дополнительного поведения (сжатия, шифрования) к базовому потоку данных.
// 1. Базовый компонент
interface DataSource {
void writeData(String data);
String readData();
}
// 2. Конкретная реализация компонента
class FileDataSource implements DataSource {
private String filename;
// ... реализация работы с файлом
public void writeData(String data) { /* запись в файл */ }
public String readData() { /* чтение из файла */ return ""; }
}
// 3. Базовый декоратор
abstract class DataSourceDecorator implements DataSource {
protected DataSource wrappee;
public DataSourceDecorator(DataSource source) {
this.wrappee = source;
}
}
// 4. Конкретные декораторы
class EncryptionDecorator extends DataSourceDecorator {
public EncryptionDecorator(DataSource source) { super(source); }
@Override
public void writeData(String data) {
String encryptedData = encrypt(data); // Логика шифрования
wrappee.writeData(encryptedData);
}
@Override
public String readData() {
String data = wrappee.readData();
return decrypt(data); // Логика дешифрования
}
// ... методы encrypt() и decrypt()
}
class CompressionDecorator extends DataSourceDecorator {
// ... аналогично, добавляет логику сжатия/распаковки
}
// 5. Использование: комбинирование декораторов
public class Client {
public static void main(String[] args) {
DataSource source = new FileDataSource("data.txt");
// Обертывание: сначала сжатие, затем шифрование
source = new CompressionDecorator(source);
source = new EncryptionDecorator(source);
source.writeData("Secret data"); // Данные будут сжаты, зашифрованы и записаны
}
}
Почему это полезно: Позволяет добавлять и комбинировать поведения во время выполнения, не создавая взрывного роста подклассов.
Ответ 18+ 🔞
Да ты посмотри, какой гибкий пиздец! Паттерн Декоратор — это как если бы ты взял обычный бутерброд и начал на него хуячить всё, что в холодильнике нашёл: колбасу, сыр, икру, блядь, майонез, огурчик. И каждый слой — это новый декоратор, а сам хлеб — это базовый компонент, ёпта.
Смотри, как это работает, на примере записи данных. Вот у тебя есть просто файл, туда можно писать и читать. Скукота, блядь.
interface DataSource {
void writeData(String data);
String readData();
}
Конкретная реализация — это просто файловая система, всё как у людей.
class FileDataSource implements DataSource {
private String filename;
// ... реализация работы с файлом
public void writeData(String data) { /* запись в файл */ }
public String readData() { /* чтение из файла */ return ""; }
}
А теперь начинается магия, ебать мои старые костыли! Мы не хотим лезть в этот класс и пихать туда всё подряд. Вместо этого мы делаем обёртку — базовый декоратор.
abstract class DataSourceDecorator implements DataSource {
protected DataSource wrappee; // Вот эта сука, которую мы оборачиваем
public DataSourceDecorator(DataSource source) {
this.wrappee = source;
}
}
И теперь мы можем накручивать функциональность, как блядские блины на Масленицу. Хочешь шифрование? Пожалуйста!
class EncryptionDecorator extends DataSourceDecorator {
public EncryptionDecorator(DataSource source) { super(source); }
@Override
public void writeData(String data) {
String encryptedData = encrypt(data); // Зашифровал, сука
wrappee.writeData(encryptedData); // Отправил дальше, по конвейеру
}
@Override
public String readData() {
String data = wrappee.readData();
return decrypt(data); // Прочитал и расшифровал
}
// ... методы encrypt() и decrypt()
}
Хочешь ещё и сжатие, чтобы место экономить? Да хуй с ним, делаем второй декоратор!
class CompressionDecorator extends DataSourceDecorator {
// ... аналогично, добавляет логику сжатия/распаковки
}
А теперь смотри, как это всё собирается в коде клиента. Это просто песня, блядь!
public class Client {
public static void main(String[] args) {
// Начинаем с голого файла
DataSource source = new FileDataSource("data.txt");
// А теперь оборачиваем, как дорогую конфету: сначала сожмём...
source = new CompressionDecorator(source);
// ...а потом зашифруем, чтобы никакой хитрожопый админ не прочитал!
source = new EncryptionDecorator(source);
// И вуаля! Записываем данные. Они пройдут через сжатие, потом шифрование и только потом в файл.
source.writeData("Secret data");
}
}
В чём, сука, кайф? А в том, что ты можешь комбинировать эти обёртки в любом порядке, да хоть на ходу менять! Не нужно городить овердохуища подклассов типа EncryptedAndCompressedFileDataSource или CompressedButNotEncryptedFileDataSource. Всё, блядь, модульно и переиспользуемо. Добавил новое поведение — написал один новый декоратор и оборачивай им что угодно. Красота, ёпта!