← Назад к вопросам
Для чего нужен шаблон Adapter?
1.8 Middle🔥 201 комментариев
#SOLID и паттерны проектирования#Spring Framework
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Паттерн Adapter в Java
Adapter (Адаптер) — это структурный паттерн проектирования, который позволяет объектам с несовместимыми интерфейсами работать вместе. Паттерн преобразует интерфейс одного класса в интерфейс, ожидаемый клиентом.
Основное назначение
Адаптер используется когда:
- Нужно использовать существующий класс, но его интерфейс несовместим с остальным кодом
- Нужно интегрировать библиотеку со старым интерфейсом в новый код
- Нужно работать с несколькими вариантами интерфейса
Реальный пример: адаптер для зарядки телефона
Телефон ожидает USB-C, но у вас есть только адаптер Micro-USB. Адаптер преобразует Micro-USB в USB-C.
Классический пример: Adapter с наследованием
// Старый интерфейс (невозможно изменить)
interface OldPaymentSystem {
void payByCash(double amount);
void payByCheck(double amount);
}
// Новый интерфейс, который ожидает приложение
interface NewPaymentGateway {
void processPayment(double amount, String method);
}
// Реализация старого интерфейса
class LegacyBank implements OldPaymentSystem {
@Override
public void payByCash(double amount) {
System.out.println("Оплата наличными: " + amount);
}
@Override
public void payByCheck(double amount) {
System.out.println("Оплата чеком: " + amount);
}
}
// Адаптер — преобразует OldPaymentSystem в NewPaymentGateway
public class PaymentAdapter implements NewPaymentGateway {
private OldPaymentSystem oldSystem;
public PaymentAdapter(OldPaymentSystem oldSystem) {
this.oldSystem = oldSystem;
}
@Override
public void processPayment(double amount, String method) {
if ("cash".equalsIgnoreCase(method)) {
oldSystem.payByCash(amount);
} else if ("check".equalsIgnoreCase(method)) {
oldSystem.payByCheck(amount);
}
}
}
// Использование
class Shop {
private NewPaymentGateway paymentGateway;
public Shop(NewPaymentGateway gateway) {
this.paymentGateway = gateway;
}
public void checkout(double amount) {
paymentGateway.processPayment(amount, "cash");
}
}
public class Main {
public static void main(String[] args) {
OldPaymentSystem oldBank = new LegacyBank();
NewPaymentGateway adapter = new PaymentAdapter(oldBank);
Shop shop = new Shop(adapter);
shop.checkout(100.0);
// Вывод: Оплата наличными: 100.0
}
}
Примеры адаптеров в Java
1. Collections.list() — адаптер Enumeration в List:
// Старый интерфейс (до Java 1.2)
Enumeration<String> oldEnum = new StringTokenizer("apple,banana,cherry", ",");
// Новый интерфейс
List<String> fruits = Collections.list(oldEnum);
for (String fruit : fruits) {
System.out.println(fruit);
}
2. Arrays.asList() — адаптер массива в List:
String[] arr = {"a", "b", "c"};
List<String> list = Arrays.asList(arr); // Адаптирует массив к List
for (String s : list) {
System.out.println(s);
}
3. InputStreamReader — адаптер InputStream в Reader:
// InputStream — работает с байтами
InputStream is = new FileInputStream("file.txt");
// Адаптируем в Reader (работает с символами)
Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8);
Adapter через наследование (Class Adapter)
class LegacySystem {
public void oldMethod() {
System.out.println("Старый метод");
}
}
// Адаптер наследует старый класс и реализует новый интерфейс
class ClassAdapter extends LegacySystem implements NewInterface {
@Override
public void newMethod() {
oldMethod(); // Переиспользуем старый метод
}
}
interface NewInterface {
void newMethod();
}
Разница: Adapter vs Bridge vs Facade
- Adapter: Преобразует несовместимые интерфейсы
- Bridge: Разделяет абстракцию от реализации (для независимого развития)
- Facade: Предоставляет упрощённый интерфейс к сложной системе
Преимущества и недостатки
Преимущества:
- Позволяет использовать несовместимые классы вместе
- Не требует изменения исходного кода
- Разделение ответственности
Недостатки:
- Добавляет новый класс в иерархию
- Может усложнить код при большом количестве адаптеров
- Производительность (если много вызовов через адаптер)