Pola State
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan PHP di Coddy. Pelajaran 79 dari 91.
State Pattern adalah pola desain perilaku yang memungkinkan sebuah object mengubah perilakunya saat status internalnya berubah. Alih-alih menggunakan percabangan yang rumit untuk menangani berbagai status, kamu mengenkapsulasi setiap status dalam class-nya sendiri dan mendelegasikan perilaku kepada object status saat ini.
Bayangkan mesin penjual otomatis. Mesin ini berperilaku berbeda bergantung pada apakah mesin sedang menunggu uang, sudah menerima pembayaran, atau sedang mengeluarkan produk.
Setiap state memiliki aturannya sendiri tentang tindakan yang diizinkan. State Pattern memodelkan hal ini dengan membuat class untuk setiap state.
<?php
interface OrderState {
public function proceed(Order $order): string;
public function getStatus(): string;
}
class PendingState implements OrderState {
public function proceed(Order $order): string {
$order->setState(new ProcessingState());
return "Order moved to processing";
}
public function getStatus(): string {
return "Pending";
}
}
class ProcessingState implements OrderState {
public function proceed(Order $order): string {
$order->setState(new ShippedState());
return "Order has been shipped";
}
public function getStatus(): string {
return "Processing";
}
}
class ShippedState implements OrderState {
public function proceed(Order $order): string {
return "Order already shipped";
}
public function getStatus(): string {
return "Shipped";
}
}
class context menyimpan referensi ke state saat ini dan mendelegasikan pemanggilan kepadanya:
<?php
class Order {
private OrderState $state;
public function __construct() {
$this->state = new PendingState();
}
public function setState(OrderState $state): void {
$this->state = $state;
}
public function proceed(): string {
return $this->state->proceed($this);
}
public function getStatus(): string {
return $this->state->getStatus();
}
}
$order = new Order();
echo $order->getStatus() . "\n";
echo $order->proceed() . "\n";
echo $order->getStatus() . "\n";
echo $order->proceed() . "\n";
echo $order->getStatus();
Output:
Pending
Order moved to processing
Processing
Order has been shipped
ShippedPola State menghilangkan pernyataan switch yang bertele-tele dan membuat penambahan state baru menjadi mudah. Setiap class state bertanggung jawab untuk mengetahui state berikutnya, sehingga logikanya tetap teratur dan mudah dipelihara.
Tantangan
MudahMari buat sistem alur kerja dokumen menggunakan State Pattern. Dokumen dalam sistem manajemen konten melewati beberapa tahap, yaitu draft, review, dan published. Setiap tahap memiliki aturan tersendiri tentang tindakan yang diizinkan dan hal yang terjadi saat kamu mencoba melanjutkan dokumen ke tahap berikutnya.
Kamu akan mengatur kodemu dalam empat file:
DocumentState.php: Definisikan interfaceDocumentStateyang menetapkan kontrak untuk semua state dokumen. Interface ini harus memiliki dua method:publish(Document $document): stringuntuk mencoba melanjutkan dokumen ke tahap berikutnya, dangetStatus(): stringuntuk mengembalikan nama state saat ini.States.php: Sertakan interface DocumentState dan buat tiga class state yang mengimplementasikannya:DraftState: Saatpublish()dipanggil, state dokumen berubah menjadiReviewStatedan mengembalikan"Document sent for review". Statusnya adalah"Draft".ReviewState: Saatpublish()dipanggil, state dokumen berubah menjadiPublishedStatedan mengembalikan"Document published". Statusnya adalah"Under Review".PublishedState: Saatpublish()dipanggil, method ini mengembalikan"Document is already published"tanpa mengubah state. Statusnya adalah"Published".
Document.php: Sertakan file States dan buat classDocumentyang bertindak sebagai context. Dokumenmu harus:- Menerima judul di constructornya dan dimulai dalam state
DraftState - Memiliki method
setState(DocumentState $state): voiduntuk mengubah state saat ini - Memiliki method
publish(): stringyang meneruskan pemanggilan ke methodpublish()pada state saat ini - Memiliki method
getStatus(): stringyang mengembalikan status state saat ini
- Menerima judul di constructornya dan dimulai dalam state
main.php: Sertakan file Document. Kamu akan menerima satu input: jumlah pemanggilanpublish()pada dokumen.Buat
Documentdengan judul"My Article". Pertama, cetak status awal. Lalu, panggilpublish()sebanyak jumlah yang ditentukan dan cetak hasil setiap pemanggilan pada baris baru. Terakhir, cetak status akhir.Format output:
Status: [initial status] [publish result 1] [publish result 2] ... Status: [final status]
Setiap class state mengetahui state berikutnya dalam alur kerja, sehingga logika transisi tetap teratur dan mudah diubah. Untuk menambahkan state baru seperti "Archived", kamu cukup membuat class baru dan memperbarui transisi yang relevan.
Coba sendiri
<?php
require_once 'Document.php';
// Baca input, yaitu jumlah pemanggilan publish()
$n = intval(trim(fgets(STDIN)));
// TODO: Buat Document dengan judul "My Article"
// TODO: Cetak status awal dengan format: "Status: [status]"
// TODO: Panggil publish() sebanyak n kali dan cetak setiap hasil pada baris baru
// TODO: Cetak status akhir dengan format: "Status: [status]"
?>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