Dekoratör Kalıbı
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 77 / 91.
Decorator Pattern, nesneleri dekoratör adı verilen özel sarmalayıcı nesnelerle sararak nesnelere dinamik olarak yeni davranışlar eklemenizi sağlayan yapısal bir tasarım desenidir. Derleme zamanında davranış ekleyen kalıtımın aksine, dekoratörler davranışı çalışma zamanında ekler.
Bir kahve dükkânı hayal et. Basit bir kahveyle başlarsın, ardından süt, şeker veya krem şanti gibi ekstralar eklersin.
Her ekleme, orijinal kahveyi sarar ve açıklamasına ve maliyetine ekleme yapar. Temel içeceğin ve dekoratörlerin aynı arayüzü paylaşması temel içgörüdür.
<?php
interface Coffee {
public function getDescription(): string;
public function getCost(): float;
}
class SimpleCoffee implements Coffee {
public function getDescription(): string {
return "Simple Coffee";
}
public function getCost(): float {
return 2.00;
}
}
Dekoratörler aynı arayüzü uygular ve başka bir Coffee nesnesini sarar:
<?php
class MilkDecorator implements Coffee {
public function __construct(private Coffee $coffee) {}
public function getDescription(): string {
return $this->coffee->getDescription() . ", Milk";
}
public function getCost(): float {
return $this->coffee->getCost() + 0.50;
}
}
class SugarDecorator implements Coffee {
public function __construct(private Coffee $coffee) {}
public function getDescription(): string {
return $this->coffee->getDescription() . ", Sugar";
}
public function getCost(): float {
return $this->coffee->getCost() + 0.25;
}
}
$coffee = new SimpleCoffee();
$coffee = new MilkDecorator($coffee);
$coffee = new SugarDecorator($coffee);
echo $coffee->getDescription() . " = $" . $coffee->getCost();
Çıktı:
Simple Coffee, Milk, Sugar = $2.75Her dekoratör, önceki nesneyi sararak bir zincir oluşturur. Bu desen, olası her kombinasyon için bir sınıf oluşturmadan davranışları istediğiniz sırada ve miktarda birleştirmenizi sağlar. Çift süt mü gerekiyor? Sadece iki kez sarın.
Görev
KolayDecorator Pattern'ı kullanarak bir pizza sipariş sistemi oluşturalım. Temel bir pizzayla başlayacak ve malzemeleri dinamik olarak ekleyeceksin: her malzeme pizzayı sarar ve derse ait kahve örneğinde olduğu gibi açıklamasına ve fiyatına ekleme yapar.
Kodunu dört dosyaya dağıtacaksın:
Pizza.php: Tüm pizzalar ve malzemeler için sözleşmeyi tanımlayan birPizzaarayüzü tanımla. İki yöntemi olmalı:getDescription(): stringvegetPrice(): float.BasePizza.php: Pizza arayüzünü dahil et ve bunu uygulayan birMargheritaPizzasınıfı oluştur. Bu, açıklaması"Margherita"ve fiyatı8.00olan temel pizzandır.Toppings.php: Pizza arayüzünü dahil et ve bunu uygulayan üç dekoratör sınıfı oluştur. Her dekoratör birPizzanesnesini sarar (nesneyi kurucuda kabul eder) ve hem açıklamayı hem de fiyatı geliştirir:CheeseTopping: Açıklamaya", Extra Cheese"ve fiyata1.50eklerPepperoniTopping: Açıklamaya", Pepperoni"ve fiyata2.00eklerMushroomTopping: Açıklamaya", Mushrooms"ve fiyata1.25ekler
main.php: BasePizza ve Toppings dosyalarını dahil et. Eklenecek malzemelerin virgülle ayrılmış bir listesini girdi olarak alacaksın (örneğin,"cheese,pepperoni"veya"mushroom,cheese,cheese").Bir
MargheritaPizzaile başla. Girdideki her malzeme için pizzanı uygun dekoratörle sar:"cheese",CheeseToppingile sarılır"pepperoni",PepperoniToppingile sarılır"mushroom",MushroomToppingile sarılır
Tüm malzemeleri uyguladıktan sonra son pizzanın açıklamasını ve fiyatını şu biçimde yazdır:
[description] = $[price]Fiyatı iki ondalık basamağa biçimlendir.
Aynı malzemenin birden fazla kez uygulanabildiğine dikkat et: iki kat peynir sipariş etmek, yalnızca CheeseTopping ile iki kez sarmak anlamına gelir. Decorator Pattern'ın gücü işte bu esnekliktir!
Kendin dene
<?php
require_once 'BasePizza.php';
require_once 'Toppings.php';
// Girdiyi oku - virgülle ayrılmış topping listesi
$input = trim(fgets(STDIN));
$toppings = explode(',', $input);
// Temel bir MargheritaPizza ile başla
$pizza = new MargheritaPizza();
// TODO: Her topping üzerinden döngü yap ve pizzayı uygun decorator ile sar
// - "cheese" -> CheeseTopping ile sar
// - "pepperoni" -> PepperoniTopping ile sar
// - "mushroom" -> MushroomTopping ile sar
// TODO: Sonucu şu formatta yazdır: [description] = $[price]
// Fiyatı number_format() kullanarak 2 ondalık basamağa biçimlendir
?>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