Menu
Coddy logo textTech

Komut Kalıbı

Coddy'nin C# Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 56 / 70.

Komut deseni, bir isteği, o istekle ilgili tüm bilgileri içeren bağımsız bir nesneye dönüştüren davranışsal bir desendir. Bu dönüşüm; istekleri metot argümanları olarak iletmenize, kuyruğa almanıza, günlüğe kaydetmenize veya geri alınabilir işlemleri desteklemenize olanak tanır.

Bu desen, bir işlemi çağıran nesneyi, işlemin nasıl gerçekleştirileceğini bilen nesneden ayırır. Dört temel bileşenden oluşur: bir komut arayüzü (command interface), somut komutlar (concrete commands), bir alıcı (receiver - asıl işi yapan nesne) ve bir çağırıcı (invoker - komutları tetikleyen nesne).

public interface ICommand
{
    void Execute();
}

public class Light  // Alıcı
{
    public void TurnOn() => Console.WriteLine("Light is ON");
    public void TurnOff() => Console.WriteLine("Light is OFF");
}

public class TurnOnCommand : ICommand
{
    private Light _light;
    
    public TurnOnCommand(Light light) => _light = light;
    
    public void Execute() => _light.TurnOn();
}

public class TurnOffCommand : ICommand
{
    private Light _light;
    
    public TurnOffCommand(Light light) => _light = light;
    
    public void Execute() => _light.TurnOff();
}

Çağırıcı (invoker), komutların ne yaptığını bilmeden onları saklar ve yürütür:

public class RemoteControl  // Çağırıcı (Invoker)
{
    private ICommand _command;
    
    public void SetCommand(ICommand command) => _command = command;
    
    public void PressButton() => _command.Execute();
}

// Kullanım
var light = new Light();
var remote = new RemoteControl();

remote.SetCommand(new TurnOnCommand(light));
remote.PressButton();  // Işık AÇIK

remote.SetCommand(new TurnOffCommand(light));
remote.PressButton();  // Işık KAPALI

Command deseni; geri alma işlevselliği, makro kaydetme veya işlemlerin daha sonra yürütülmek üzere kuyruğa alınması için özellikle güçlüdür. Her komut, bir eylemi gerçekleştirmek için gereken her şeyi kapsüller, bu da sisteminizi daha esnek ve genişletilebilir hale getirir.

challenge icon

Görev

Kolay

Komut (Command) desenini kullanarak bir metin düzenleyici komut sistemi oluşturalım. Metin ekleme ve silme gibi düzenleme işlemlerinin komut nesneleri olarak kapsüllendiği ve düzenleyicinin bunları birleşik bir arayüz üzerinden yürütmesine olanak tanıyan bir sistem oluşturacaksınız.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • Command.cs: TextEditor ad alanında (namespace), tek bir Execute() metoduna sahip bir ICommand arayüzü tanımlayın. Ardından iki somut komut sınıfı oluşturun:
    • InsertCommand - yapıcı metodunda (constructor) bir Document ve bir string text alır. Yürütüldüğünde, metni belgeye ekler ve Inserted: {text} yazdırır.
    • DeleteCommand - yapıcı metodunda bir Document ve bir int count alır. Yürütüldüğünde, belgeden son count karakteri siler ve Deleted: {count} characters yazdırır.
  • Document.cs: Aynı ad alanında bir Document sınıfı oluşturun. Bu sizin alıcınızdır (receiver) - metin işlemlerini asıl gerçekleştiren nesne. Şunlara sahip olmalıdır:
    • İçeriği saklamak için özel (private) bir string alanı (boş dize olarak başlatın)
    • İçeriğe metin ekleyen bir Append(string text) metodu
    • Son count karakteri silen bir RemoveLast(int count) metodu (eğer count içerik uzunluğunu aşarsa, tüm içeriği temizleyin)
    • Mevcut içeriği döndüren bir GetContent() metodu
  • Program.cs: Çağırıcı (invoker) görevi gören bir Editor sınıfı oluşturun. Bir SetCommand(ICommand command) metoduna ve mevcut komutu çalıştıran bir ExecuteCommand() metoduna sahip olmalıdır. Ana kodunuzda, bir dizi düzenleme işlemini işleyerek komut desenini gösterin.

Aşağıdaki girdileri alacaksınız:

  • Yürütülecek komut sayısı
  • Her komut için: komut türü (insert veya delete) ve ardından eklenecek metin veya silinecek karakter sayısı

Tüm komutları yürüttükten sonra, son belge içeriğini yeni bir satırda Content: {content} formatında yazdırın.

Örneğin, girdiler şunlarsa:

4
insert
Hello
insert
 World
delete
3
insert
!

Çıktı şöyle olmalıdır:

Inserted: Hello
Inserted:  World
Deleted: 3 characters
Inserted: !
Content: Hello Wo!

Editor'ün (çağırıcı) metin manipülasyonu hakkında hiçbir şey bilmediğine dikkat edin - sadece kendisine verilen komutu yürütür. Komutlar hem eylemi hem de alıcıyı kapsüller, bu da düzenleyiciyi değiştirmeden ReplaceCommand gibi yeni işlemler eklemeyi kolaylaştırır!

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 desendir. Bu, istekleri metot argümanları olarak iletmenize, kuyruğa almanıza, günlüğe kaydetmenize veya geri alınabilir işlemleri desteklemenize olanak tanır.

Desenin dört ana bileşeni vardır:

  • Komut arayüzü (Command interface) - Execute() metodunu tanımlar
  • Somut komutlar (Concrete commands) - komut arayüzünü uygular ve belirli eylemleri kapsüller
  • Alıcı (Receiver) - asıl işi gerçekleştiren nesne
  • Çağırıcı (Invoker) - komutları, uygulamalarını bilmeden tetikleyen nesne

Komut Arayüzü ve Somut Komutlar

public interface ICommand
{
    void Execute();
}

public class TurnOnCommand : ICommand
{
    private Light _light;
    
    public TurnOnCommand(Light light) => _light = light;
    
    public void Execute() => _light.TurnOn();
}

public class TurnOffCommand : ICommand
{
    private Light _light;
    
    public TurnOffCommand(Light light) => _light = light;
    
    public void Execute() => _light.TurnOff();
}

Alıcı

public class Light
{
    public void TurnOn() => Console.WriteLine("Light is ON");
    public void TurnOff() => Console.WriteLine("Light is OFF");
}

Çağırıcı

public class RemoteControl
{
    private ICommand _command;
    
    public void SetCommand(ICommand command) => _command = command;
    
    public void PressButton() => _command.Execute();
}

Kullanım

var light = new Light();
var remote = new RemoteControl();

remote.SetCommand(new TurnOnCommand(light));
remote.PressButton();  // Işık AÇIK

remote.SetCommand(new TurnOffCommand(light));
remote.PressButton();  // Işık KAPALI

Komut deseni; geri alma işlevselliği, makro kaydetme veya işlemlerin daha sonra yürütülmek üzere kuyruğa alınması için kullanışlıdır. Her komut, bir eylemi gerçekleştirmek için gereken her şeyi kapsülleyerek sistemleri daha esnek ve genişletilebilir hale getirir.

Kendin dene

using System;
using TextEditor;

// TODO: Editor sınıfını oluşturun (invoker)
public class Editor
{
    // TODO: Mevcut komutu saklamak için özel bir alan ekleyin
    private ICommand _command;

    // TODO: SetCommand metodunu uygulayın
    public void SetCommand(ICommand command)
    {
        // TODO: Komutu saklayın
    }

    // TODO: ExecuteCommand metodunu uygulayın
    public void ExecuteCommand()
    {
        // TODO: Mevcut komutu çalıştırın
    }
}

class Program
{
    public static void Main(string[] args)
    {
        // Komut sayısını oku
        int n = Convert.ToInt32(Console.ReadLine());

        // Belgeyi oluşturun (receiver)
        Document document = new Document();

        // Editörü oluşturun (invoker)
        Editor editor = new Editor();

        // TODO: Her komutu işleyin
        for (int i = 0; i < n; i++)
        {
            string commandType = Console.ReadLine();

            // TODO: commandType değerine göre uygun komutu oluşturun
            // - Eğer "insert" ise: metni oku ve InsertCommand oluştur
            // - Eğer "delete" ise: sayıyı oku ve DeleteCommand oluştur
            // Ardından komutu editöre atayın ve çalıştırın
        }

        // TODO: Nihai içeriği "Content: {content}" formatında 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