Ответ
Adapter (Адаптер) — это структурный паттерн проектирования, который позволяет объектам с несовместимыми интерфейсами работать вместе. Он выступает в роли «переводчика» или «обёртки», преобразуя интерфейс одного класса в интерфейс, ожидаемый клиентом.
Когда использовать:
- Интеграция legacy-кода или сторонних библиотек, интерфейс которых нельзя изменить.
- Необходимость использовать несколько классов с разными интерфейсами, но схожей функциональностью, через единый интерфейс.
- Создание слоя совместимости между системами.
Реализация (пример на Java): Допустим, есть старый сервис отправки SMS и новый клиентский код, ожидающий современный интерфейс.
// 1. Старый класс (Adaptee), который нужно адаптировать
class LegacySmsSender {
public void sendSms(String phoneNumber, String messageText) {
System.out.println("[Legacy] Sending SMS to " + phoneNumber + ": " + messageText);
}
}
// 2. Целевой интерфейс (Target), который ожидает клиент
interface ModernMessenger {
void send(String recipient, String content);
}
// 3. Адаптер (Adapter) – реализует целевой интерфейс и содержит ссылку на Adaptee
class SmsAdapter implements ModernMessenger {
private final LegacySmsSender legacySender;
public SmsAdapter(LegacySmsSender legacySender) {
this.legacySender = legacySender;
}
@Override
public void send(String recipient, String content) {
// Преобразование вызова нового интерфейса в старый
legacySender.sendSms(recipient, content);
}
}
// 4. Клиентский код
public class Client {
public static void main(String[] args) {
LegacySmsSender oldService = new LegacySmsSender();
ModernMessenger messenger = new SmsAdapter(oldService); // Обёртка
// Клиент работает через ModernMessenger, не зная о LegacySmsSender
messenger.send("+79991234567", "Hello via Adapter!");
}
}
Преимущества:
- Отделяет и скрывает код преобразования интерфейсов от бизнес-логики.
- Повышает переиспользуемость кода, позволяя использовать несовместимые классы.
- Соответствует принципу единственной ответственности (SRP) – преобразование интерфейса вынесено в отдельный класс.
Недостатки:
- Усложняет код за счёт введения дополнительных классов. Следует применять обоснованно, а не для связи любых интерфейсов.