Ответ
Adapter — это структурный паттерн проектирования, который позволяет объектам с несовместимыми интерфейсами работать вместе. Он выступает в роли "переводчика" или "прослойки" между клиентом и адаптируемым сервисом.
Аналогия: Электрический адаптер, позволяющий вилке одного стандарта работать в розетке другого.
Реализация в Java:
// 1. Целевой интерфейс, который ожидает клиент (например, розетка USB-C)
interface UsbCCharger {
void chargeWithUsbC();
}
// 2. Адаптируемый класс со старым интерфейсом (например, зарядка MicroUSB)
class MicroUsbCharger {
public void chargeWithMicroUsb() {
System.out.println("Charging with MicroUSB...");
}
}
// 3. Адаптер, реализующий целевой интерфейс и содержащий ссылку на адаптируемый объект
class MicroUsbToUsbCAdapter implements UsbCCharger {
private MicroUsbCharger microUsbCharger;
public MicroUsbToUsbCAdapter(MicroUsbCharger microUsbCharger) {
this.microUsbCharger = microUsbCharger;
}
@Override
public void chargeWithUsbC() {
// Адаптер преобразует вызов нового метода в вызов старого
microUsbCharger.chargeWithMicroUsb();
System.out.println(" (via Adapter)");
}
}
// 4. Клиентский код, который работает только с целевым интерфейсом
public class Client {
public static void main(String[] args) {
MicroUsbCharger oldCharger = new MicroUsbCharger();
// Используем адаптер для подключения старой зарядки к новому устройству
UsbCCharger adapter = new MicroUsbToUsbCAdapter(oldCharger);
adapter.chargeWithUsbC(); // Вывод: Charging with MicroUSB... (via Adapter)
}
}
Когда использовать:
- Интеграция старого (legacy) кода в новую систему.
- Использование сторонних библиотек с неподходящим интерфейсом.
- Создание универсального интерфейса для работы с несколькими классами, имеющими разную функциональность.
Плюсы:
- Отделяет и скрывает код преобразования интерфейсов от бизнес-логики.
- Повышает переиспользуемость кода.
Минусы:
- Усложняет систему за счет введения дополнительных классов.
Ответ 18+ 🔞
Слушай, а вот есть у тебя, допустим, зарядка от старого телефона — MicroUSB, а новый смартфон требует USB-C. И что, выкидывать старую? Да хуй там! Берёшь переходничек, воткни его — и работает. Этот переходничек в мире кода и есть Adapter, ёпта.
Этот паттерн — как раз такая прослойка-переводчик между двумя объектами, которые друг друга нахуй послать готовы из-за разных интерфейсов. Клиент хочет одно, а сервис умеет только другое. Адаптер берёт и говорит: «Да похуй, я переведу».
Как это выглядит в коде, на примере этих ебучих зарядок:
// 1. Это то, что хочет твой новый телефон (USB-C розетка)
interface UsbCCharger {
void chargeWithUsbC();
}
// 2. А это твоя старая зарядка, которая умеет только так
class MicroUsbCharger {
public void chargeWithMicroUsb() {
System.out.println("Charging with MicroUSB...");
}
}
// 3. А вот и наш герой — переходник-адаптер!
class MicroUsbToUsbCAdapter implements UsbCCharger {
private MicroUsbCharger microUsbCharger; // держит ссылку на старую хрень
public MicroUsbToUsbCAdapter(MicroUsbCharger microUsbCharger) {
this.microUsbCharger = microUsbCharger;
}
@Override
public void chargeWithUsbC() {
// Магия здесь: он принимает вызов нового метода...
microUsbCharger.chargeWithMicroUsb(); // ...и внутри дергает старый
System.out.println(" (via Adapter)");
}
}
// 4. Клиент (твой телефон) думает, что работает с USB-C, а по факту...
public class Client {
public static void main(String[] args) {
MicroUsbCharger oldCharger = new MicroUsbCharger(); // старая зарядка
// Обманываем систему адаптером
UsbCCharger adapter = new MicroUsbToUsbCAdapter(oldCharger);
adapter.chargeWithUsbC(); // Вывод: Charging with MicroUSB... (via Adapter)
}
}
Когда эту хуйню применять?
- Когда нужно впихнуть старый легаси-код в новую систему, а переписывать его — овердохуища работы.
- Когда используешь стороннюю библиотеку, у которой интерфейс кривой как рога у козла.
- Когда хочешь сделать универсальную заглушку для кучи классов с разными методами.
Плюсы:
- Разделяет ответственность: весь этот пиздец с преобразованием интерфейсов сидит в одном месте, а не размазан по всей логике.
- Повышает переиспользуемость: старый код можно таскать за собой, как чемодан без ручки, и везде подключать через адаптер.
Минусы:
- Усложняет архитектуру: появляются эти ебучие классы-прослойки, которых с каждым днём всё больше. Иногда проще нахуй послать и переписать.