Menu
Coddy logo textTech

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 OFF

Komut 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.

challenge icon

Görev

Kolay

Komut 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 bir execute(): string metoduna sahip bir Command arayü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 bir TextEditor sı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 bir write(string $text): string metoduna sahip olmalıdır
    • İçeriği boşaltan ve "Content cleared" döndüren bir clear(): string metoduna sahip olmalıdır
    • Mevcut içeriği döndüren bir getContent(): string metoduna sahip olmalıdır
  • Commands.php — Command ve TextEditor dosyalarını dahil edin. Command arayüzünü uygulayan iki komut sınıfı oluşturun:
    • WriteCommand — Yapıcısında (constructor) bir TextEditor ve bir metin dizesi alır. execute() metodu, düzenleyicinin write() metodunu çağırır ve sonucu döndürür.
    • ClearCommand — Yapıcısında bir TextEditor alır. execute() metodu, düzenleyicinin clear() 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 üzerinde execute() 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 sadece Content: 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)

?>
quiz iconKendini test et

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