State Pattern (Durum Tasarım Kalıbı), bir nesnenin iç durumuna bağlı olarak farklı davranışlar sergilemesini sağlayan bir davranışsal tasarım desenidir. Bu desen, nesnenin durumunu ayrı sınıflar halinde tanımlayarak, davranışların koşullara bağlı olarak değişmesini yönetmeyi kolaylaştırır.
Ne Zaman Kullanılmalıdır?
State Pattern şu durumlarda kullanışlıdır:
- Bir nesnenin farklı iç durumlara bağlı olarak farklı davranışlar sergilemesi gerektiğinde.
- Büyük if-else veya switch-case bloklarından kaçınmak istendiğinde.
- Bir nesnenin durumları arasında geçiş yapmasının daha modüler ve esnek hale getirilmesi gerektiğinde.
- Bir nesnenin davranışlarının genişletilebilir ve bakımının kolay olması gerektiğinde.
State Pattern’in Avantajları ve Dezavantajları
Avantajlar:
- Daha modüler ve okunabilir kod: Nesnenin her durumu ayrı bir sınıf olarak tanımlanır.
- Koşullu ifadeleri (if-else/switch-case) ortadan kaldırır.
- Genişletilebilirliği artırır: Yeni durumlar eklemek için mevcut kodda değişiklik yapmak yerine, yeni sınıflar oluşturulabilir.
Dezavantajlar:
- Her durum için ayrı bir sınıf oluşturma ihtiyacı, kodun karmaşıklığını artırabilir.
- Basit senaryolar için gereksiz soyutlama olabilir.
State Pattern Kullanım Biçimleri
1. Durum Arayüzü ve Concrete State Sınıfları
// State Arayüzü
interface State {
void handleRequest();
}
// Concrete State 1: Açık Durumu
class OnState implements State {
@Override
public void handleRequest() {
System.out.println("Cihaz şu an AÇIK.");
}
}
// Concrete State 2: Kapalı Durumu
class OffState implements State {
@Override
public void handleRequest() {
System.out.println("Cihaz şu an KAPALI.");
}
}
2. Context Sınıfı (Durumları Yöneten Sınıf)
class Device {
private State state;
public Device() {
this.state = new OffState(); // Varsayılan olarak kapalı
}
public void setState(State state) {
this.state = state;
}
public void pressPowerButton() {
state.handleRequest();
if (state instanceof OffState) {
setState(new OnState());
} else {
setState(new OffState());
}
}
}
3. Kullanım
public class Main {
public static void main(String[] args) {
Device device = new Device();
device.pressPowerButton(); // Cihaz şu an AÇIK.
device.pressPowerButton(); // Cihaz şu an KAPALI.
}
}
Çıktı:
Cihaz şu an AÇIK.
Cihaz şu an KAPALI.
Gerçek Dünya Senaryosu: Trafik Işıkları
// State Arayüzü
interface TrafficLightState {
void change(TrafficLight trafficLight);
}
// Concrete State: Kırmızı Işık
class RedLight implements TrafficLightState {
@Override
public void change(TrafficLight trafficLight) {
System.out.println("Kırmızı ışık - Dur!");
trafficLight.setState(new GreenLight());
}
}
// Concrete State: Yeşil Işık
class GreenLight implements TrafficLightState {
@Override
public void change(TrafficLight trafficLight) {
System.out.println("Yeşil ışık - Devam et!");
trafficLight.setState(new YellowLight());
}
}
// Concrete State: Sarı Işık
class YellowLight implements TrafficLightState {
@Override
public void change(TrafficLight trafficLight) {
System.out.println("Sarı ışık - Hazır ol!");
trafficLight.setState(new RedLight());
}
}
// Context Sınıfı
class TrafficLight {
private TrafficLightState state;
public TrafficLight() {
this.state = new RedLight(); // Varsayılan durum
}
public void setState(TrafficLightState state) {
this.state = state;
}
public void changeLight() {
state.change(this);
}
}
Kullanım
public class Main {
public static void main(String[] args) {
TrafficLight trafficLight = new TrafficLight();
trafficLight.changeLight(); // Kırmızı ışık -> Yeşil ışık
trafficLight.changeLight(); // Yeşil ışık -> Sarı ışık
trafficLight.changeLight(); // Sarı ışık -> Kırmızı ışık
}
}
Çıktı:
Kırmızı ışık - Dur!
Yeşil ışık - Devam et!
Sarı ışık - Hazır ol!
Sonuç
State Design Pattern, nesnenin iç durumuna göre davranış değiştirmesini sağlayarak kodun daha esnek ve yönetilebilir hale gelmesini sağlar. Gerçek dünyada şu senaryolarda yaygın olarak kullanılır:
- Trafik ışıkları yönetimi
- Sipariş yönetim sistemleri (Ödeme bekleniyor, Kargoya verildi, Teslim edildi vs.)
- Oyun geliştirme (Karakterin farklı modları: saldırı, savunma, kaçış vb.)
- Medya oynatıcılar (Oynatılıyor, Duraklatıldı, Durduruldu)
State Pattern sayesinde, bir nesnenin davranışı if-else veya switch-case bloklarıyla yönetilmek yerine durum nesneleri aracılığıyla esnek bir şekilde değiştirilir. 🚀