Arayüzler Yoluyla Çok Biçimlilik
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 34 / 91.
Önceki derste, alt sınıfların üst sınıf metotlarını geçersiz kıldığı kalıtım yoluyla çok biçimliliği gördün. Arayüzler, özellikle ortak davranışları paylaşan ve birbiriyle ilişkili olmayan sınıflarla çalışırken, çok biçimliliğe ulaşmak için başka bir güçlü yol sunar.
Arayüzlerle birlikte polimorfizm sözleşmenin kendisinden gelir. Bir arayüzü uygulayan herhangi bir sınıf, kalıtım hiyerarşisinden bağımsız olarak belirli methodlara sahip olduğunu garanti eder:
<?php
interface Notifiable {
public function send(string $message);
}
class EmailNotifier implements Notifiable {
public function send(string $message) {
return "Email: " . $message;
}
}
class SMSNotifier implements Notifiable {
public function send(string $message) {
return "SMS: " . $message;
}
}
class PushNotifier implements Notifiable {
public function send(string $message) {
return "Push: " . $message;
}
}
function notify(Notifiable $notifier, string $message) {
return $notifier->send($message);
}
echo notify(new EmailNotifier(), "Hello") . "\n";
echo notify(new SMSNotifier(), "Hello") . "\n";
echo notify(new PushNotifier(), "Hello");
Çıktı:
Email: Hello
SMS: Hello
Push: Hellonotify() işlevi, herhangi bir Notifiable nesnesiyle çalışır. Bu sınıflar ortak bir üst sınıfı paylaşmaz; aynı arayüzü uygulamaları dışında birbirleriyle tamamen ilgisizdirler. Kalıtım tabanlı çok biçimliliğe kıyasla temel avantaj şudur: ilgisiz sınıfları soylarına göre değil, yeteneklerine göre gruplayabilirsiniz.
Temel Nokta: Arayüz tabanlı çok biçimlilik, ortak davranışa dayalı olarak birbiriyle ilişkili olmayan sınıfların birbirinin yerine kullanılmasını sağlar; bu da kodunuzu daha esnek ve belirli uygulamalardan daha bağımsız hâle getirir.
Görev
KolayArayüz tabanlı çok biçimliliği gösteren bir depolama sistemi oluşturalım. Birbirleriyle hiçbir ortak noktası olmayan, ancak her ikisi de aynı depolama arayüzünü uygulayan farklı depolama arka uçları, bir dosya sistemi ve bir veritabanı oluşturacaksın. Tek bir işlev herhangi bir depolama türüyle çalışacak ve arayüzlerin tamamen ilgisiz sınıflar arasında çok biçimliliği nasıl mümkün kıldığını gösterecek.
Kodunu dört dosyaya ayıracaksın:
Storable.php: İki yöntem imzasına sahip birStorablearayüzü tanımla:save($key, $data)veretrieve($key). Bu sözleşme, herhangi bir depolama sisteminin dahili olarak nasıl uygulandığından bağımsız olarak veri depolayabilmesini ve alabilmesini sağlar.FileStorage.php:Storableuygulayan birFileStoragesınıfı oluştur. Arayüz dosyasını dahil et. Sınıfın, oluşturucu aracılığıyla ayarlanan private bir$directoryözelliği olmalı.save($key, $data)yöntemini"Saving '[data]' to file [directory]/[key].txt"döndürecek şekilde uygula.retrieve($key)yöntemini"Reading from file [directory]/[key].txt"döndürecek şekilde uygula.DatabaseStorage.php: Aynı zamandaStorableuygulayan birDatabaseStoragesınıfı oluştur. Arayüz dosyasını dahil et. Sınıfın, oluşturucu aracılığıyla ayarlanan private bir$tableNameözelliği olmalı.save($key, $data)yöntemini"Inserting '[data]' into table [tableName] with key [key]"döndürecek şekilde uygula.retrieve($key)yöntemini"Selecting from table [tableName] where key = [key]"döndürecek şekilde uygula.main.php: Her iki depolama dosyasını dahil et. BirStorableparametresi, bir anahtar ve veri kabul edenstoreDataadlı bir işlev oluştur. İşlev, anahtar ve verilerlesave()çağrısının sonucunu döndürmeli. BirStorableparametresi ve bir anahtar kabul eden,retrieve()çağrısının sonucunu döndürenfetchDataadlı başka bir işlev oluştur.
Dört girdi alacaksın: bir dizin yolu, bir tablo adı, bir anahtar ve depolanacak bazı veriler. Dizinle bir FileStorage ve tablo adıyla bir DatabaseStorage oluştur. Verileri önce dosya depolamasını, ardından veritabanı depolamasını kullanarak kaydetmek için storeData() işlevini kullan. Her sonucu kendi satırına yazdır. Ardından dosya depolamasından veri almak için fetchData() işlevini kullan ve bu sonucu yazdır.
storeData() ve fetchData() işlevlerinin her iki depolama türüyle de aynı şekilde çalıştığına dikkat et. Bu işlevler yalnızca nesnenin Storable uygulamasını önemser. Dosya sistemi ve veritabanı tamamen farklı dahili uygulamalara sahip olsa da arayüz sözleşmesi sayesinde birbirlerinin yerine kullanılabilirler.
Kendin dene
<?php
require_once 'FileStorage.php';
require_once 'DatabaseStorage.php';
// Girdileri oku
$directory = trim(fgets(STDIN));
$tableName = trim(fgets(STDIN));
$key = trim(fgets(STDIN));
$data = trim(fgets(STDIN));
// TODO: Storable, key ve data kabul eden bir storeData fonksiyonu oluştur
// key ve data ile save() çağrısının sonucunu döndürmelidir
// TODO: Storable ve key kabul eden bir fetchData fonksiyonu oluştur
// key ile retrieve() çağrısının sonucunu döndürmelidir
// TODO: directory ile bir FileStorage örneği oluştur
// TODO: tablo adıyla bir DatabaseStorage örneği oluştur
// TODO: Dosya depolama ile veriyi kaydetmek için storeData() kullan, ardından sonucu yazdır
// TODO: Veritabanı depolama ile veriyi kaydetmek için storeData() kullan, ardından sonucu yazdır
// TODO: Use fetchData() to retrieve from file storage, then print the result
?>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
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesneler$this Anahtar SözcüğüMetotlarÖzelliklerYapıcı (__construct)Yıkıcı (__destruct)Tekrar - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımparent:: Anahtar SözcüğüMetot Geçersiz Kılmafinal Anahtar SözcüğüSoyut SınıflarTekrar - Çalışan Hiyerarşisi7Kapsülleme
Public, Protected, PrivateErişim Belirleyicileri DerinlemesineGetter ve Setter'larBilgi GizlemeYapıcı Özellik Terfisi (8.0)Tekrar - Öğrenci Kayıt Sistemi10İleri Düzey OOP Kavramları
Composition ve KalıtımBağımlılık EnjeksiyonuAnonim SınıflarEnum'lar (PHP 8.1)Fiber'lar (PHP 8.1)Nesne Klonlamaya Derinlemesine BakışÜreteçler ve Yineleyiciler13Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıBileşik KalıpDepo Kalıbı2Namespace’ler ve Autoloading
Namespace’lere Girişuse Anahtar SözcüğüPSR-4 Autoloading StandardıComposer AutoloaderTekrar - Düzenli Proje5Arayüzler ve Sözleşmeler
Arayüzlere GirişArayüzleri UygulamaBirden Çok Arayüz UygulamaArayüz ve Soyut Sınıf KarşılaştırmasıArayüzlerle Tür İpuçlarıTekrar - Şekil Hesaplayıcı8Sihirli Metotlar
Sihirli Metotlara Giriş__toString ve __debugInfo__get, __set, __isset, __unset__call ve __callStatic__clone ve Nesne Klonlama__serialize ve __unserializeTekrar - Özel Koleksiyon3Sınıf Özellikleri
Örnek ve Statik ÖzelliklerSınıflarda SabitlerStatik Metotlar ve ÖzelliklerPrivate ve Protected ÖzelliklerSalt Okunur Özellikler (PHP 8.1)Tekrar - Banka Hesabı Yöneticisi6Çok Biçimlilik
Metot Geçersiz Kılmayı Yeniden Ele AlmaArayüzler Yoluyla Çok BiçimlilikTür İpuçları ve Birleşim TürleriGeç Bağlanan Statik ÇağrılarÖzet - Ödeme İşlemcisi9Trait'ler
Trait'lere GirişBirden Çok Trait KullanımıTrait Çakışmalarını ÇözümlemeTrait'lerde Soyut MetotlarTrait'ler ve Kalıtım Karşılaştırması12Tasarım Desenleri 1. Bölüm
Tasarım Desenlerine GirişSingleton DeseniFactory DeseniObserver DeseniStrategy DeseniKendi başına pratik yap: Online PHP derleyicisi