Komut Kalıbı
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 70 / 87.
Komut Deseni (Command Pattern), bir isteği, 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.
Bunu bir restoran gibi düşünün: aşçıya doğrudan ne pişireceğini söylemek yerine, siparişinizi bir fişe yazarsınız. Garson (invoker), fişi (command) mutfağa götürür; burada fiş sıraya alınabilir, önceliklendirilebilir veya hatta iptal edilebilir. Bu desen, işlemi çağıran nesne ile işlemi gerçekleştiren nesneyi birbirinden ayırır.
Kalıbın dört ana bileşeni vardır: execute metodunu bildiren bir Command arayüzü, belirli eylemleri gerçekleştiren ConcreteCommand sınıfları, asıl işi yapan bir Receiver ve komutları tetikleyen bir Invoker:
interface Command {
void execute();
}class Light { // Alıcı
public void turnOn() {
System.out.println("Light is ON");
}
public void turnOff() {
System.out.println("Light is OFF");
}
}class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.turnOn();
}
}class RemoteControl { // Çağırıcı
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}Çağırıcı hangi işlemin gerçekleştirileceğini bilmez—sadece execute() metodunu çağırır:
Light light = new Light();
Command lightOn = new LightOnCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton(); // Çıktı: Işık AÇIKKomut Deseni (Command Pattern); işlemleri kuyruğa almanız, geri al/yinele işlevselliği uygulamanız veya görevleri daha sonra yürütülmek üzere zamanlamanız gerektiğinde mükemmel sonuçlar verir. 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 Desenini (Command Pattern) kullanarak akıllı bir ev otomasyon sistemi kuralım! Çeşitli ev cihazlarının komutlar aracılığıyla kontrol edilebildiği, eylemlerin sıraya alınabildiği, yürütülebildiği ve hatta daha sonra kullanılmak üzere saklanabildiği bir sistem oluşturacaksınız; tıpkı her cihazın dahili olarak nasıl çalıştığını bilmesine gerek duymayan evrensel bir uzaktan kumanda gibi.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Command.java: Tüm cihaz komutlarının uygulayacağıCommandarayüzünü tanımlayın. Komutun eylemini gerçekleştiren tek birexecute()metodu bildirmelidir.Devices.java: Akıllı ev cihazlarını temsil eden iki alıcı (receiver) sınıfı oluşturun:Television-TV is now ONyazdıranpowerOn(),TV is now OFFyazdıranpowerOff()veTV channel set to [channel]yazdıransetChannel(int channel)metodlarına sahiptir.Thermostat-Thermostat set to [temp] degreesyazdıransetTemperature(int temp)veThermostat turned OFFyazdıranturnOff()metodlarına sahiptir.Commands.java: Cihaz işlemlerini kapsülleyen somut komut sınıfları oluşturun:TVOnCommand- Yapıcısında (constructor) birTelevisionalır ve yürütüldüğündepowerOn()metodunu çağırır.TVOffCommand- Yapıcısında birTelevisionalır ve yürütüldüğündepowerOff()metodunu çağırır.TVChannelCommand- Yapıcısında birTelevisionve birint channelalır ve yürütüldüğünde bu kanallasetChannel()metodunu çağırır.ThermostatSetCommand- Yapıcısında birThermostatve birint temperaturealır ve yürütüldüğünde bu değerlesetTemperature()metodunu çağırır.Main.java: Bir komutu saklamak içinsetCommand(Command cmd)metoduna ve saklanan komutu yürütmek içinpressButton()metoduna sahip birRemoteControlsınıfı (çağırıcı/invoker) oluşturun.Ana metodunuzda (main method) iki girdi alacaksınız: bir TV kanal numarası (tam sayı) ve bir termostat sıcaklığı (tam sayı).
Bir
Televisionve birThermostatoluşturun. BirRemoteControloluşturun ve Komut Desenini şu şekilde gösterin:- Bir
TVOnCommandayarlayın ve düğmeye basın - Girdi kanalınızla bir
TVChannelCommandayarlayın ve düğmeye basın - Girdi sıcaklığınızla bir
ThermostatSetCommandayarlayın ve düğmeye basın - Bir
TVOffCommandayarlayın ve düğmeye basın
- Bir
Sırasıyla iki girdi alacaksınız: TV kanalı (tam sayı) ve termostat sıcaklığı (tam sayı).
Örneğin, 5 ve 72 girdileriyle çıktınız şöyle olacaktır:
TV is now ON
TV channel set to 5
Thermostat set to 72 degrees
TV is now OFFRemoteControl sınıfının cihazlarla asla doğrudan etkileşime girmediğine, yalnızca Command arayüzünü bildiğine dikkat edin. Her komut, eylemini gerçekleştirmek için gereken her şeyi kapsüller, bu da çağırıcıyı değiştirmeden yeni cihazlar ve komutlar eklemeyi kolaylaştırır!
Kopya kağıdı
Komut Deseni (Command Pattern), bir isteği nesne olarak kapsülleyen, istemcileri farklı isteklerle parametreleştirmenize, istekleri kuyruğa almanıza veya günlüğe kaydetmenize ve geri alınabilir işlemleri desteklemenize olanak tanıyan davranışsal bir tasarım desenidir.
Bu desen, işlemi başlatan nesneyi (invoker) işlemi gerçekleştiren nesneden (receiver) ayırır.
Temel Bileşenler
- Command:
execute()metodunu bildiren arayüz (interface) - ConcreteCommand: Belirli eylemleri uygulayan sınıflar
- Receiver: Gerçek işi yapan nesne
- Invoker: Komutları tetikleyen nesne
Temel Yapı
// Command arayüzü
interface Command {
void execute();
}
// Receiver (Alıcı)
class Light {
public void turnOn() {
System.out.println("Light is ON");
}
public void turnOff() {
System.out.println("Light is OFF");
}
}
// ConcreteCommand (Somut Komut)
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.turnOn();
}
}
// Invoker (Başlatıcı)
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}Kullanım
Light light = new Light();
Command lightOn = new LightOnCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton(); // Çıktı: Light is ONBaşlatıcı (invoker) hangi eylemin gerçekleştirileceğini bilmez; sadece execute() metodunu çağırır. Bu, sistemi esnek ve genişletilebilir hale getirir; işlemleri kuyruğa almak, geri al/yinele (undo/redo) işlevselliğini uygulamak veya görevleri zamanlamak için idealdir.
Kendin dene
import java.util.Scanner;
// TODO: RemoteControl sınıfını (çağırıcı/invoker) şunlarla oluşturun:
// - bir komutu saklamak için setCommand(Command cmd) metodu
// - saklanan komutu çalıştırmak için pressButton() metodu
class RemoteControl {
// TODO: RemoteControl sınıfını uygulayın
}
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Girdileri oku
int channel = scanner.nextInt();
int temperature = scanner.nextInt();
// TODO: Bir Television ve bir Thermostat oluşturun
// TODO: Bir RemoteControl oluşturun
// TODO: Command Pattern'i gösterin:
// 1. Bir TVOnCommand ayarlayın ve düğmeye basın
// 2. Giriş kanalıyla bir TVChannelCommand ayarlayın ve düğmeye basın
// 3. Giriş sıcaklığıyla bir ThermostatSetCommand ayarlayın ve düğmeye basın
// 4. Bir TVOffCommand ayarlayın ve düğmeye basın
scanner.close();
}
}
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 Nesnelerthis Anahtar KelimesiMetotlarAlanlar (Öznitelikler)Yapıcı MetotYapıcı Metot Aşırı YüklemeÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (extends)super Anahtar KelimesiMetot Geçersiz Kılma (@Override)Yapıcı Metot ZincirlemeObject SınıfıTekli ve Çok Seviyeli KalıtımNeden Çoklu Sınıf Kalıtımı Yok?Özet - Çalışan Hiyerarşisi7Özel Metotlar ve Object Sınıfı
toString() Metoduequals() ve hashCode()clone() MetoducompareTo() ve ComparableComparator ArayüzüÖzet - Özel Sıralama2Erişim Belirleyiciler ve Kapsülleme
Erişim Seviyelerine Genel BakışGetter ve Setter MetotlarıBilgi Gizlemefinal Anahtar KelimesiÖzet - Banka Hesabı Yöneticisi5Polimorfizm
Metot Aşırı Yükleme TemelleriMetot Geçersiz Kılma (Çalışma Zamanı)Upcasting ve Downcastinginstanceof OperatörüSoyut Sınıflar ve MetotlarÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımAgregasyon vs KompozisyonDahili, Yuvalanmış ve Anonim SınıflarEnum'lar ve Enum MetotlarıRecords (Java 16+)Sealed Classes (Java 17+)11Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıBuilder KalıbıObserver KalıbıStrategy Kalıbı14Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi3Sınıf Özellikleri ve Statik Üyeler
Instance ve Statik DeğişkenlerStatik MetotlarStatik BloklarSabitler (static final)Özet - Sayaç ve Utility6Arayüzler ve Soyut Sınıflar
Arayüzlere GirişArayüzleri UygulamaÇoklu Arayüz UygulamaArayüzlerde Default ve StaticSoyut Sınıflar ve ArayüzlerFonksiyonel ArayüzlerÖzet - Ödeme Sistemi9Generics
Generics'e GirişGeneric SınıflarGeneric MetotlarSınırlandırılmış Tip ParametreleriWildcard'lar (?, extends, super)Özet - Generic Container12Tasarı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ıYineleyici Kalıbı