Усі три загортають інші об'єкти, але з різною метою:
Adapter - змінює інтерфейс: приводить чужий об'єкт до інтерфейсу, який очікує ваш код.
final class TwilioSmsAdapter implements SmsSender // ваш інтерфейс
{
public function __construct(private TwilioClient $twilio) {}
public function send(PhoneNumber $to, string $text): void
{
$this->twilio->messages->create((string) $to, ['body' => $text, 'from' => '...']);
}
}
Decorator - той самий інтерфейс, додана поведінка. Загортає об'єкт і додає щось до або після виклику; декоратори можна нашаровувати.
final class CachedExchangeRates implements ExchangeRates
{
public function __construct(private ExchangeRates $inner, private CacheRepository $cache) {}
public function rate(string $from, string $to): float
{
return $this->cache->remember("rate:$from:$to", 3600, fn () => $this->inner->rate($from, $to));
}
}
Кешування, логування, повтори, метрики - типові декоратори. Обгорнутий і обгортка взаємозамінні.
Facade (класичний, GoF) - спрощений інтерфейс до складної підсистеми: один клас з кількома простими методами замість десятка класів з тонкими налаштуваннями.
Фасади Laravel (Cache::, DB::) - інше: це статичний доступ до сервісів з контейнера (ближче до Service Locator). Назва схожа, але патерн GoF не про це.
Як розрізнити на співбесіді:
- інтерфейс змінюється - Adapter;
- інтерфейс той самий, поведінки більше - Decorator;
- інтерфейс простіший за те, що за ним, - Facade.
Ще схожий Proxy - той самий інтерфейс, але контролює доступ до об'єкта: ліниве створення, перевірка прав, віддалений виклик.