Menu
Coddy logo textTech

Adaptör Kalıbı

Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 76 / 91.

Adapter Deseni, uyumsuz arayüzlere sahip nesnelerin birlikte çalışmasına olanak tanıyan yapısal bir tasarım desenidir. İki arayüz arasında bir köprü görevi görerek çağrıları bir formattan diğerine çevirir.

Ödemeleri işleyen bir uygulama oluşturduğunuzu ve üçüncü taraf bir ödeme kütüphanesini entegre etmeniz gerektiğini hayal edin. Kütüphane mükemmel çalışıyor, ancak arayüzü kodunuzun beklediğiyle eşleşmiyor. Tüm uygulamanızı yeniden yazmak yerine, ikisi arasında çeviri yapan bir adaptör oluşturursunuz.

<?php
// Uygulamanızın beklediği arayüz
interface PaymentProcessor {
    public function pay(float $amount): string;
}

// Farklı bir arayüze sahip üçüncü taraf kütüphanesi
class StripeAPI {
    public function createCharge(int $cents, string $currency): string {
        return "Charged {$cents} {$currency} via Stripe";
    }
}

Adaptör, dahili olarak üçüncü taraf sınıfı kullanırken beklediğiniz arayüzü uygular:

<?php
class StripeAdapter implements PaymentProcessor {
    public function __construct(private StripeAPI $stripe) {}
    
    public function pay(float $amount): string {
        $cents = (int)($amount * 100);
        return $this->stripe->createCharge($cents, 'USD');
    }
}

$stripe = new StripeAPI();
$processor = new StripeAdapter($stripe);
echo $processor->pay(29.99);

Çıktı:

Charged 2999 USD via Stripe

Adaptör, dolarları sente dönüştürür ve uygun metodu çağırır. Uygulama kodunuz yalnızca PaymentProcessor yapısını bilir ve Stripe'ın özel gereksinimlerinden tamamen habersiz kalır. Daha sonra farklı bir ödeme sağlayıcısına geçerseniz, mevcut kodunuzu değiştirmeden sadece yeni bir adaptör oluşturursunuz.

challenge icon

Görev

Kolay

Adapter Desenini kullanarak bir sıcaklık dönüştürme sistemi oluşturalım. Elinizde Fahrenhayt cinsinden okuma yapan eski bir sıcaklık sensörü var, ancak modern hava durumu uygulamanız tüm sıcaklıkların Santigrat (Celsius) cinsinden olmasını bekliyor. Her iki sistemi de değiştirmek yerine, aradaki boşluğu dolduran bir adaptör oluşturacaksınız.

Kodunuzu dört dosya halinde düzenleyeceksiniz:

  • TemperatureSensor.php — Hava durumu uygulamanızın beklediği bir TemperatureSensor arayüzü (interface) tanımlayın. Bu arayüz, Santigrat cinsinden sıcaklığı döndüren bir getTemperature(): float metoduna sahip olmalıdır.
  • LegacySensor.php — Eski donanımı simüle eden bir LegacySensor sınıfı oluşturun. Bu sınıf, uygulamanızın ihtiyaç duyduğundan farklı bir arayüze sahiptir:
    • Yapıcısında (constructor) bir Fahrenhayt değeri alır (constructor promotion kullanın)
    • Saklanan Fahrenhayt değerini döndüren bir readFahrenheit(): float metoduna sahiptir
  • LegacySensorAdapter.php — Hem TemperatureSensor arayüzünü hem de LegacySensor sınıfını dahil edin. TemperatureSensor arayüzünü uygulayan ve bir LegacySensor nesnesini sarmalayan bir LegacySensorAdapter sınıfı oluşturun. Adaptörünüz şunları yapmalıdır:
    • Yapıcısında bir LegacySensor kabul etmelidir
    • Eski sensörden Fahrenhayt değerini okuyup (fahrenheit - 32) * 5 / 9 formülünü kullanarak Santigrat'a dönüştürerek getTemperature() metodunu uygulamalıdır
  • main.php — LegacySensorAdapter dosyasını dahil edin. Bir girdi alacaksınız: Fahrenhayt cinsinden bir sıcaklık.

    Girdi sıcaklığı ile bir LegacySensor oluşturun, ardından bunu bir LegacySensorAdapter içine sarmalayın. Adaptör üzerinde getTemperature() metodunu çağırın ve sonucu virgülden sonra iki basamağa yuvarlayarak yazdırın.

    Çıktı formatı şu şekilde olmalıdır: Temperature: [celsius]C

Bu zorluk, Adapter Deseninin mevcut kodu değiştirmeden uyumsuz arayüzleri nasıl entegre etmenize izin verdiğini gösterir. Hava durumu uygulamanız yalnızca TemperatureSensor arayüzü ile çalışır ve gerçek okumaların eski bir Fahrenhayt sensöründen geldiğinden tamamen habersizdir.

Kopya kağıdı

Adapter Pattern (Adaptör Deseni), uyumsuz arayüzlere sahip nesnelerin aralarında bir köprü görevi görerek birlikte çalışmasını sağlayan yapısal bir tasarım desenidir.

Temel Yapı

Uygulamanızın beklediği arayüzü tanımlayın:

<?php
interface PaymentProcessor {
    public function pay(float $amount): string;
}

Farklı bir arayüzü olan üçüncü taraf bir sınıf:

<?php
class StripeAPI {
    public function createCharge(int $cents, string $currency): string {
        return "Charged {$cents} {$currency} via Stripe";
    }
}

Adaptörü Oluşturma

Adaptör, beklenen arayüzü uygularken dahili olarak üçüncü taraf sınıfı kullanır:

<?php
class StripeAdapter implements PaymentProcessor {
    public function __construct(private StripeAPI $stripe) {}
    
    public function pay(float $amount): string {
        $cents = (int)($amount * 100);
        return $this->stripe->createCharge($cents, 'USD');
    }
}

Kullanım

$stripe = new StripeAPI();
$processor = new StripeAdapter($stripe);
echo $processor->pay(29.99);
// Çıktı: Charged 2999 USD via Stripe

Adaptör, arayüzler arasında çeviri yaparak, üçüncü taraf kütüphaneleri entegre ederken veya uygulamaları değiştirirken uygulama kodunuzun değişmeden kalmasını sağlar.

Kendin dene

<?php
require_once 'LegacySensorAdapter.php';

// Girişi oku
$fahrenheit = floatval(trim(fgets(STDIN)));

// YAPILACAK: Giriş sıcaklığı ile bir LegacySensor oluşturun
// YAPILACAK: Bunu bir LegacySensorAdapter içine sarın
// YAPILACAK: Adaptör üzerinde getTemperature() metodunu çağırın
// YAPILACAK: Sonucu iki ondalık basamağa yuvarlayarak yazdırın
// Çıktı formatı: Temperature: [celsius]C

?>
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler