Ответ
Паттерн Адаптер (Adapter) преобразует интерфейс одного класса в интерфейс, ожидаемый клиентом. Он позволяет несовместимым классам работать вместе.
Пример: Интеграция старой системы логирования с новым интерфейсом приложения.
// 1. Целевой интерфейс, который ожидает клиент (новая система)
interface NewLogger {
void logMessage(String message);
}
// 2. Адаптируемый класс (старая, несовместимая система)
class LegacyLogger {
public void log(String msg, String level) {
System.out.println("[" + level + "]: " + msg);
}
}
// 3. Адаптер, реализующий целевой интерфейс и использующий старый класс
class LoggerAdapter implements NewLogger {
private LegacyLogger legacyLogger;
public LoggerAdapter(LegacyLogger logger) {
this.legacyLogger = logger;
}
@Override
public void logMessage(String message) {
// Адаптация вызова: используем уровень по умолчанию для старого метода
legacyLogger.log(message, "INFO");
}
}
// 4. Использование клиентом
public class Client {
public static void main(String[] args) {
NewLogger logger = new LoggerAdapter(new LegacyLogger());
logger.logMessage("Application started"); // Вывод: [INFO]: Application started
}
}
Почему это полезно: Позволяет повторно использовать существующий код, не изменяя его, и соблюдает принцип открытости/закрытости (Open/Closed Principle).
Ответ 18+ 🔞
Да ты посмотри, какой прикольный паттерн — Адаптер! Это ж как переходник в розетку, блядь. У тебя есть старая, ебучка, система, которая работает по-своему, а новая требует другого интерфейса. И что, переписывать всё с нуля? Да хуй там! Берёшь этот адаптер, и он как мужик-переводчик между двумя бабами, которые друг друга не понимают: одной говорит одно, другой — другое, а в итоге все довольны и работа кипит.
Смотри, как это выглядит в коде, тут всё чётко:
// 1. Это наш новый, модный интерфейс, который все хотят видеть
interface NewLogger {
void logMessage(String message);
}
// 2. А это старая система, которая орет как сумасшедшая на своём диалекте
class LegacyLogger {
public void log(String msg, String level) {
System.out.println("[" + level + "]: " + msg);
}
}
// 3. И вот наш герой — Адаптер! Он надевает маску нового интерфейса, а внутри крутит старые шестерёнки
class LoggerAdapter implements NewLogger {
private LegacyLogger legacyLogger;
public LoggerAdapter(LegacyLogger logger) {
this.legacyLogger = logger;
}
@Override
public void logMessage(String message) {
// А тут магия: новый вызов превращаем в старый, подсовывая дефолтный уровень
legacyLogger.log(message, "INFO");
}
}
// 4. Клиент, который даже не в курсе, что под капотом древний монстр
public class Client {
public static void main(String[] args) {
NewLogger logger = new LoggerAdapter(new LegacyLogger());
logger.logMessage("Application started"); // И на тебе: [INFO]: Application started
}
}
А полезность-то, блядь, в чём? Да в том, что ты не ломаешь старый, проверенный годами код, который, может, ещё и не твой был. Принцип открытости/закрытости, ёпта! Система открыта для расширения (новый адаптер прикрутил), но закрыта для изменений (старый код не тронул). Красота, да и только!