Komut Kalıbı
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 75 / 91.
Komut Deseni (Command Pattern), bir isteği, o istekle ilgili tüm bilgileri içeren bağımsız bir nesneye dönüştüren davranışsal bir tasarım desenidir. Bu dönüşüm, istekleri metot argümanları olarak iletmenize, bir isteğin yürütülmesini geciktirmenize veya sıraya koymanıza ve geri alınabilir işlemleri desteklemenize olanak tanır.
Bir restoran düşünün.
Yemek sipariş ettiğinizde, garson siparişinizi bir fişe (komut) yazar, mutfağa götürür ve aşçı bunu uygular. Garsonun nasıl yemek pişirileceğini bilmesine gerek yoktur; sadece komutu iletirler.
Bu, isteği yapanı yürütücüden ayırır.
İşte temel bir uygulama:
<?php
interface Command {
public function execute(): string;
}class Light {
public function on(): string { return "Light is ON"; }
public function off(): string { return "Light is OFF"; }
}class LightOnCommand implements Command {
public function __construct(private Light $light) {}
public function execute(): string {
return $this->light->on();
}
}class LightOffCommand implements Command {
public function __construct(private Light $light) {}
public function execute(): string {
return $this->light->off();
}
}
Çağırıcı (invoker), komutların ne yaptığını bilmeden onları tetikler:
<?php
class RemoteControl {
public function press(Command $command): string {
return $command->execute();
}
}$light = new Light();
$remote = new RemoteControl();
echo $remote->press(new LightOnCommand($light)) . "\n";
echo $remote->press(new LightOffCommand($light));
Çıktı:
Light is ON
Light is OFFKomut Deseni (Command Pattern), işlemleri kuyruğa almanız, geri alma işlevselliği uygulamanız veya eylemleri günlüğe kaydetmeniz gerektiğinde mükemmeldir. Her komut bağımsızdır, bu da mevcut kodu değiştirmeden yeni komutlar eklemeyi kolaylaştırır.
Görev
KolayKomut Desenini (Command Pattern) kullanarak bir metin düzenleyici komut sistemi oluşturalım. Metin düzenleyiciler genellikle metin yazma, metin silme ve işlemleri geri alma gibi işlemleri desteklemeye ihtiyaç duyarlar — her işlem, birleşik bir arayüz üzerinden yürütülebilen bağımsız bir komut nesnesi haline gelir.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Command.php— Tek birexecute(): stringmetoduna sahip birCommandarayüzü tanımlayın. Bu, tüm düzenleyici komutlarının uyması gereken sözleşmeyi belirler.TextEditor.php— Alıcıyı (receiver) — yani işi asıl yapan nesneyi — temsil eden birTextEditorsınıfı oluşturun. Düzenleyiciniz şunları yapmalıdır:- Mevcut metin içeriğini saklamalıdır (boş bir dize ile başlayın)
- İçeriğe metin ekleyen ve
"Written: [text]"döndüren birwrite(string $text): stringmetoduna sahip olmalıdır - İçeriği boşaltan ve
"Content cleared"döndüren birclear(): stringmetoduna sahip olmalıdır - Mevcut içeriği döndüren bir
getContent(): stringmetoduna sahip olmalıdır
Commands.php— Command ve TextEditor dosyalarını dahil edin.Commandarayüzünü uygulayan iki komut sınıfı oluşturun:WriteCommand— Yapıcısında (constructor) birTextEditorve bir metin dizesi alır.execute()metodu, düzenleyicininwrite()metodunu çağırır ve sonucu döndürür.ClearCommand— Yapıcısında birTextEditoralır.execute()metodu, düzenleyicininclear()metodunu çağırır ve sonucu döndürür.
main.php— Commands dosyasını dahil edin. İki girdi alacaksınız: bir komut türü ("write"veya"clear") ve bir metin dizesi (yalnızca yazma komutları için kullanılır).Bir
TextEditorörneği oluşturun. Komut türüne bağlı olarak uygun komut nesnesini oluşturun. Ardından, komut üzerindeexecute()metodunu çağıran ve sonucu yazdıran bir çağırıcı (invoker) fonksiyonu veya basit bir mekanizma oluşturun.Yeni bir satırda, düzenleyicinin mevcut içeriğini şu formatta yazdırın:
Content: [content](eğer boşsa, boşluktan sonra hiçbir şey olmadan sadeceContent:yazdırın).
Bu meydan okuma, Komut Deseninin her bir işlemi bir nesne olarak nasıl kapsüllediğini gösterir. Çağırıcı (invoker), bir yazma mı yoksa temizleme komutu mu yürüttüğünü bilmek zorunda değildir — sadece execute() metodunu çağırır ve ayrıntıları komutun halletmesine izin verir.
Kopya kağıdı
Komut Deseni (Command Pattern), bir isteği, istekle ilgili tüm bilgileri içeren bağımsız bir nesne olarak kapsülleyen davranışsal bir tasarım desenidir. Bu, istekleri metot argümanları olarak iletmenize, işlemleri kuyruğa almanıza ve geri alınabilir eylemleri desteklemenize olanak tanır.
Desen, bir garsonun nasıl yemek pişirileceğini bilmesine gerek kalmadan siparişleri aşçıya iletmesine benzer şekilde, isteği yapanı (invoker) yürütücüden (receiver) ayırır.
Temel Yapı
Bir execute() metodu içeren bir Command arayüzü tanımlayın:
interface Command {
public function execute(): string;
}Gerçek işi gerçekleştiren bir alıcı (receiver) sınıfı oluşturun:
class Light {
public function on(): string { return "Light is ON"; }
public function off(): string { return "Light is OFF"; }
}Belirli eylemleri kapsülleyen somut komut sınıflarını uygulayın:
class LightOnCommand implements Command {
public function __construct(private Light $light) {}
public function execute(): string {
return $this->light->on();
}
}
class LightOffCommand implements Command {
public function __construct(private Light $light) {}
public function execute(): string {
return $this->light->off();
}
}Çağırıcı (Invoker)
Çağırıcı, uygulama detaylarını bilmeden komutları tetikler:
class RemoteControl {
public function press(Command $command): string {
return $command->execute();
}
}
$light = new Light();
$remote = new RemoteControl();
echo $remote->press(new LightOnCommand($light)) . "\n";
echo $remote->press(new LightOffCommand($light));Avantajlar
Komut Deseni; işlemleri kuyruğa almak, geri alma işlevini uygulamak veya eylemleri günlüğe kaydetmek için idealdir. Her komut kendi kendine yeterlidir, bu da mevcut kodu değiştirmeden yeni komutlar eklemeyi kolaylaştırır.
Kendin dene
<?php
require_once 'Commands.php';
// Girdiyi oku
$commandType = trim(fgets(STDIN)); // "write" veya "clear"
$text = trim(fgets(STDIN)); // yazma komutu için metin
// TODO: Bir TextEditor örneği oluşturun
// TODO: Komut türüne bağlı olarak uygun komut nesnesini oluşturun
// - Eğer "write" ise, editör ve metin ile bir WriteCommand oluşturun
// - Eğer "clear" ise, editör ile bir ClearCommand oluşturun
// TODO: Komut üzerinde execute() metodunu çağıran ve sonucu yazdıran
// bir invoker (çağırıcı) mekanizması oluşturun
// TODO: Editörün mevcut içeriğini şu formatta yazdırın: "Content: [content]"
// (eğer boşsa, boşluktan sonra hiçbir şey olmadan sadece "Content: " yazdırın)
?>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 KelimesiMetotlarÖzelliklerYapıcı Metot (__construct)Yıkıcı Metot (__destruct)Özet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımparent:: Anahtar KelimesiMetot Geçersiz Kılmafinal Anahtar KelimesiSoyut SınıflarÖzet - Çalışan Hiyerarşisi7Kapsülleme
Public, Protected, PrivateErişim Belirleyicilere Derinlemesine BakışGetter ve Setter MetotlarıBilgi GizlemeConstructor Promotion (8.0)Özet - Öğrenci Kayıt Sistemi10İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımDependency InjectionAnonim SınıflarEnum'lar (PHP 8.1)Fiber'lar (PHP 8.1)Nesne Klonlama: Derinlemesine İncelemeGenerator'lar ve Iterator'lar13Tasarı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ıKompozit KalıbıRepository Kalıbı2İsim Alanları ve Autoloading
İsim Alanlarına Girişuse Anahtar KelimesiPSR-4 Autoloading StandartıComposer AutoloaderÖzet - Düzenli Proje5Arayüzler ve Sözleşmeler
Arayüzlere GirişArayüzleri UygulamaBirden Fazla Arayüz UygulamaArayüz vs Soyut SınıfArayüzler ile Tip BelirlemeÖzet - Şekil Hesaplayıcı8Sihirli Metotlar
Sihirli Metotlara Giriş__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Nesne Klonlama__serialize & __unserializeÖzet - Özel Koleksiyon3Sınıf Özellikleri
Örnek ve Statik ÖzelliklerSınıflarda SabitlerStatik Metotlar ve ÖzelliklerPrivate ve Protected ÖzelliklerReadonly Özellikler (PHP 8.1)Özet - Banka Hesabı Yöneticisi6Çok Biçimlilik
Metot Geçersiz Kılmaya Yeniden BakışArayüzler ile Çok BiçimlilikType Hinting ve Union TypesLate Static BindingÖzet - Ödeme İşlemcisi9Trait'ler
Trait'lere GirişÇoklu Trait KullanımıTrait Çakışma ÇözümüTrait'lerde Soyut MetotlarTrait'ler ve Kalıtım12Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı15Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi