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 KAPALICommand 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.
Görev
KolayKomut (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:TextEditorad alanında (namespace), tek birExecute()metoduna sahip birICommandarayüzü tanımlayın. Ardından iki somut komut sınıfı oluşturun:InsertCommand- yapıcı metodunda (constructor) birDocumentve bir stringtextalır. Yürütüldüğünde, metni belgeye ekler veInserted: {text}yazdırır.DeleteCommand- yapıcı metodunda birDocumentve birint countalır. Yürütüldüğünde, belgeden soncountkarakteri siler veDeleted: {count} charactersyazdırır.
Document.cs: Aynı ad alanında birDocumentsı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
countkarakteri silen birRemoveLast(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 birEditorsınıfı oluşturun. BirSetCommand(ICommand command)metoduna ve mevcut komutu çalıştıran birExecuteCommand()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ü (
insertveyadelete) 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 KAPALIKomut 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
}
}
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 Dosyalarİsim Alanları ve YönergelerSınıf ve Nesnelere Giriş'this' Anahtar KelimesiMetotlar ve ParametrelerAlanlar ve ÖzelliklerYapıcı MetotlarNesne BaşlatıcılarÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (:) Sözdizimi'base' Anahtar KelimesiVirtual ve Override Anahtar KelimeleriSealed Sınıflar'object' Temel SınıfıÖzet - Çalışan Hiyerarşisi7İleri Düzey Özellikler
Operatör Aşırı Yüklemeİndeksleyiciler (this[])ToString() Geçersiz KılmaGenişletme MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişThread-Safe SingletonFactory KalıbıObserver Kalıbı (Olaylar)Strategy Kalıbı2Özellikler ve Statik Üyeler
Otomatik Uygulanan ÖzelliklerSadece Okunur/Yazılır ÖzelliklerStatik Alanlar ve MetotlarStatik Sınıflarİfade Gövdeli Üyeler5Polimorfizm ve Arayüzler
Derleme vs Çalışma Zamanı PolimorfizmiArayüz vs Soyut SınıfÇoklu ArayüzlerBelirgin ArayüzlerUpcasting ve DowncastingÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kalıtım yerine KompozisyonGenerics (Sınıflar ve Metotlar)Delegates ve EventlerAttributes ve ReflectionIDisposable ve using İfadesiDependency Injection Temelleri11Tasarı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ı3Sınıf Mimarisi
Örnek vs Statik Veri'readonly' ve 'const' Anahtar KelimeleriDestekleyici Alanlar (Backing Fields)Özet - Banka Hesabı Yöneticisi6Kapsülleme
Erişim BelirleyicilerKapsülleme için ÖzelliklerVeri Gizleme UygulamasıDeğişmezlik KalıplarıÖzet - Öğrenci Kayıtları