Ответ
Структурные паттерны — это паттерны проектирования, которые описывают способы компоновки объектов и классов в более крупные, гибкие и эффективные структуры, сохраняя при этом их расширяемость.
Паттерн Адаптер (Adapter) позволяет объектам с несовместимыми интерфейсами работать вместе. Он выступает в роли «переводчика» или «прослойки» между клиентом и адаптируемым сервисом.
Аналогия: Переходник с USB-C на USB-A позволяет новому ноутбуку работать со старой флешкой.
Пример реализации в Java:
// 1. Целевой интерфейс, который ожидает клиент (USB-порт)
interface UsbConnector {
void connectUsb();
}
// 2. Адаптируемый класс со своим специфическим интерфейсом (старая флешка с USB-A)
class LegacyUsbPort {
public void plugIn() {
System.out.println("Legacy USB device connected.");
}
}
// 3. Адаптер. Реализует целевой интерфейс и содержит ссылку на адаптируемый объект.
class UsbAdapter implements UsbConnector {
private LegacyUsbPort legacyPort;
public UsbAdapter(LegacyUsbPort legacyPort) {
this.legacyPort = legacyPort;
}
@Override
public void connectUsb() {
// Адаптер «переводит» вызов connectUsb() в вызов plugIn()
legacyPort.plugIn();
}
}
// 4. Клиентский код, который работает только с целевым интерфейсом
public class ModernLaptop {
public void useDevice(UsbConnector connector) {
connector.connectUsb();
}
public static void main(String[] args) {
ModernLaptop laptop = new ModernLaptop();
LegacyUsbPort oldFlashDrive = new LegacyUsbPort();
// Используем адаптер для подключения старого устройства
UsbConnector adapter = new UsbAdapter(oldFlashDrive);
laptop.useDevice(adapter); // Вывод: "Legacy USB device connected."
}
}
Когда использовать Адаптер:
- Интеграция старого (legacy) кода с новой системой.
- Использование сторонних библиотек с интерфейсом, отличным от ожидаемого в вашем приложении.
- Создание унифицированного интерфейса для работы с несколькими классами, имеющими разные API.
Ответ 18+ 🔞
А, паттерны проектирования, ёпта! Ну, структурные, говоришь? Это те, которые как конструктор лего, только для кода — из мелких деталек собираешь что-то большое и не разваливающееся нахуй при первом же чихе.
Вот смотри, первый на очереди — Адаптер. Представь себе такую хуйню: у тебя есть новый ноутбук, весь такой блядский, с USB-C, а флешка — старая, с USB-A, как кирпич. И что, выкидывать её? Не, чувак, ты берёшь переходник — вот это и есть адаптер, сука! Он делает вид, что он USB-C, а внутри него спрятана старая разъёбина, и всё работает. В рот меня чих-пых, гениально же!
В коде это выглядит примерно так, смотри, не зевай:
// 1. Это то, что твой новый код хочет видеть (USB-C порт, блядь)
interface UsbConnector {
void connectUsb();
}
// 2. А это старая хрень, которая у тебя уже есть (флешка-кирпич с USB-A)
class LegacyUsbPort {
public void plugIn() {
System.out.println("Legacy USB device connected.");
}
}
// 3. А вот и наш герой — ПЕРЕХОДНИК, ёбаный адаптер!
class UsbAdapter implements UsbConnector {
private LegacyUsbPort legacyPort; // Внутри него спрятана старая штука
public UsbAdapter(LegacyUsbPort legacyPort) {
this.legacyPort = legacyPort;
}
@Override
public void connectUsb() {
// А тут магия: он кричит "connectUsb!", а сам внутри делает "plugIn!"
legacyPort.plugIn(); // Переводчик, блядь, между двумя мирами!
}
}
// 4. А это ты, со своим новым ноутом, который нихуя не понимает в старье
public class ModernLaptop {
public void useDevice(UsbConnector connector) {
connector.connectUsb();
}
public static void main(String[] args) {
ModernLaptop laptop = new ModernLaptop();
LegacyUsbPort oldFlashDrive = new LegacyUsbPort(); // Вот она, древность
// Берём адаптер, натягиваем его на старую флешку как презерватив
UsbConnector adapter = new UsbAdapter(oldFlashDrive);
laptop.useDevice(adapter); // И вуаля — работает! Вывод: "Legacy USB device connected."
}
}
Так когда же эту штуку впендюривать?
- Когда тебе нужно впихнуть старый, легаси-код, написанный ещё при царе Горохе, в свою новую, блестящую систему. Чтобы не переписывать всё, блядь, с нуля.
- Когда используешь какую-то библиотеку от чуваков, у которых API кривой, как рога барана, а твой код хочет общаться красиво.
- Когда нужно сделать одного общего утконоса из кучи разных классов, которые говорят на разных языках. Адаптер — он как переводчик-синхронист, только для объектов, ёпта!