Pola Decorator
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan PHP di Coddy. Pelajaran 77 dari 91.
Decorator Pattern adalah pola desain struktural yang memungkinkan kamu menambahkan perilaku baru ke object secara dinamis dengan membungkusnya dalam object pembungkus khusus yang disebut decorator. Tidak seperti pewarisan, yang menambahkan perilaku saat kompilasi, decorator menambahkan perilaku saat runtime.
Bayangkan sebuah kedai kopi. Kamu mulai dengan kopi dasar, lalu menambahkan pelengkap seperti susu, gula, atau krim kocok.
Setiap tambahan membungkus kopi asli dan menambahkan deskripsi serta biayanya. Inti utamanya adalah kopi dasar dan dekorator menggunakan antarmuka yang sama.
<?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;
}
}
Decorator menerapkan antarmuka yang sama dan membungkus object Coffee lain:
<?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();
Output:
Simple Coffee, Milk, Sugar = $2.75Setiap decorator membungkus object sebelumnya, membentuk rantai. Pola ini memungkinkan kamu menggabungkan berbagai perilaku dalam urutan dan jumlah apa pun tanpa membuat class untuk setiap kombinasi yang mungkin. Butuh dua porsi susu? Bungkus saja dua kali.
Tantangan
MudahMari kita buat sistem pemesanan pizza menggunakan Decorator Pattern. Kamu akan memulai dengan pizza dasar, lalu menambahkan topping secara dinamis: setiap topping membungkus pizza dan menambahkan deskripsi serta harganya, seperti contoh kopi dalam pelajaran.
Kamu akan menyusun kodemu dalam empat file:
Pizza.php: Definisikan interfacePizzayang menetapkan kontrak untuk semua pizza dan topping. Interface ini harus memiliki dua method:getDescription(): stringdangetPrice(): float.BasePizza.php: Sertakan interface Pizza dan buat classMargheritaPizzayang mengimplementasikannya. Ini adalah pizza dasarmu dengan deskripsi"Margherita"dan harga8.00.Toppings.php: Sertakan interface Pizza dan buat tiga class dekorator yang mengimplementasikannya. Setiap dekorator membungkus objectPizza(terima object tersebut di constructor) dan menambahkan deskripsi serta harga:CheeseTopping: Menambahkan", Extra Cheese"ke deskripsi dan1.50ke hargaPepperoniTopping: Menambahkan", Pepperoni"ke deskripsi dan2.00ke hargaMushroomTopping: Menambahkan", Mushrooms"ke deskripsi dan1.25ke harga
main.php: Sertakan file BasePizza dan Toppings. Kamu akan menerima satu input: list topping yang dipisahkan dengan koma untuk ditambahkan (misalnya,"cheese,pepperoni"atau"mushroom,cheese,cheese").Mulailah dengan
MargheritaPizza. Untuk setiap topping dalam input, bungkus pizzamu dengan dekorator yang sesuai:"cheese"dibungkus denganCheeseTopping"pepperoni"dibungkus denganPepperoniTopping"mushroom"dibungkus denganMushroomTopping
Setelah menerapkan semua topping, cetak deskripsi dan harga akhir pizza dengan format ini:
[description] = $[price]Format harga hingga dua angka desimal.
Perhatikan bahwa topping yang sama dapat diterapkan beberapa kali: memesan keju ekstra berarti membungkusnya dengan CheeseTopping dua kali. Inilah keunggulan Decorator Pattern!
Coba sendiri
<?php
require_once 'BasePizza.php';
require_once 'Toppings.php';
// Baca input berupa list topping yang dipisahkan koma
$input = trim(fgets(STDIN));
$toppings = explode(',', $input);
// Mulai dengan MargheritaPizza sebagai dasar
$pizza = new MargheritaPizza();
// TODO: Ulangi setiap topping dan bungkus pizza dengan decorator yang sesuai
// - "cheese" -> bungkus dengan CheeseTopping
// - "pepperoni" -> bungkus dengan PepperoniTopping
// - "mushroom" -> bungkus dengan MushroomTopping
// TODO: Cetak hasil dalam format: [description] = $[price]
// Format harga menjadi 2 angka di belakang koma menggunakan number_format()
?>Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP
File EksternalPengenalan OOPclass vs objectKata Kunci $thismethodpropertyConstructor (__construct)Destructor (__destruct)Ringkasan: Kalkulator Sederhana4Pewarisan
Pewarisan DasarKata Kunci parent::Penimpaan methodKata Kunci finalClass AbstrakRingkasan: Hierarki Karyawan7Enkapsulasi
Public, Protected, PrivateModifier Akses secara MendalamGetter dan SetterPenyembunyian InformasiPromosi Constructor (8.0)Ulasan: Sistem Catatan Siswa10Konsep OOP Lanjutan
Komposisi vs PewarisanInjeksi Dependensiclass AnonimEnum (PHP 8.1)Fiber (PHP 8.1)Pendalaman Kloning objectGenerator dan Iterator13Pola Desain Bagian 2
Pola PerintahPola AdapterPola DecoratorPola Template MethodPola StatePola CompositePola Repository2Namespace dan Autoloading
Pengenalan NamespaceKata Kunci useStandar Autoloading PSR-4Autoloader ComposerRingkasan: Proyek yang Terorganisasi5Interface dan Kontrak
Pengenalan InterfaceMengimplementasikan InterfaceImplementasi Beberapa InterfaceInterface vs Abstract ClassPetunjuk Tipe dengan InterfaceRekap: Kalkulator Bentuk8Magic Methods
Pengantar Magic Methods__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Cloning Object__serialize & __unserializeRingkasan: Koleksi Kustom11Sistem Tipe Data dan Penanganan Error
Deklarasi TipeTipe NullableTipe Union dan IntersectionClass ExceptionHierarki Exception KustomTry, Catch, FinallyRekap: Validator Form3Property dalam class
Property instance vs staticKonstanta dalam classMethod & property staticProperty private & protectedProperty readonly (PHP 8.1)Ulasan: Pengelola Rekening Bank6Polimorfisme
Meninjau Kembali Method OverridingPolimorfisme melalui AntarmukaPetunjuk Tipe dan Tipe UnionPengikatan Statis TertundaRangkuman: Pemroses PembayaranLatihan sendiri: Compiler PHP online