Davranışsal Kalıplar — State, Chain of Responsibility, Command
Önce şunu oku: Tasarım Kalıpları — Ne Zaman Kazandırır
30 saniyede özet
Bir nesnenin davranışı durumuna göre değişiyorsa durumu açıkça say; üç ayrı true/false, anlamsız karışımlara izin verir. Sıralı kontroller için zincir kur, sonraya bırakılacak isteği bir nesneye çevir.
Bir sipariş hem iptal edilmiş hem kargoda. Müşteri parasını geri aldı, paket de kapısına geldi. Kodda yanlış bir satır yok; sadece bir kontrol eksik.
-
Bayt: Bir sipariş hem iptal edilmiş hem kargoda! Müşteri hem parasını aldı hem paketini.
-
Sen: Kodda bir hata mı var?
-
Bayt: Yanlış satır yok. Sadece üç ayrı düğme, olmaması gereken bir karışıma izin veriyor.
-
Bayt: Kaç karışım mümkün, kaçı anlamlı? Önce sen say.
State: durumu açıkça say
Sipariş isPaid, isShipped, isCancelled boolean'larıyla tutuluyor. Kaç farklı kombinasyon mümkün ve kaçı anlamlı? Cevabı göster
Sekiz kombinasyon, ama anlamlı olan yalnızca birkaçı. “Kargoda ama ödenmemiş” ya da “iptal edilmiş ama kargoda” da kodun izin verdiği durumlardır.
Adım adım oku
- Sipariş durumu üç ayrı boolean ile tutuluyor: ödendi, kargoda, iptal. Birlikte sekiz karışım mümkün.
- Kargoda ve iptal düğmeleri aynı anda açılabiliyor: iptal edilmiş ama kargoda bir sipariş.
- Durum tek bir açık tipe taşınınca, yani tek bir anahtar olunca, her pozisyonun adı var.
- Anahtar aynı anda yalnızca bir pozisyonda durur. Anlamsız bir durum artık yazılamaz.
StateDavranış duruma göre değişiyorsa durumu açık bir tip olarak tutup her durumda izin verilen işlemleri tanımlamak. Geçersiz kombinasyonlar ifade edilemez olur.Sözlükte gör → kalıbı durumu tek bir alan olarak tutar ve her durumda hangi işlemin izinli olduğunu tanımlar. Geçersiz kombinasyonlar ifade edilemez hâle gelir.
Kafam karıştı, daha basit anlat
Üç ayrı evet/hayır kutucuğu, “iptal edildi ama kargoda” gibi saçma durumlara izin verir. Durumu tek bir alanda tutarsan, sipariş aynı anda yalnızca tek bir yerde olabilir.
Bir siparişin durumunu `isPaid`, `isShipped`, `isCancelled` boolean'larıyla tutmanın temel sorunu nedir?
Bir durum makinesinde geçersiz bir geçiş istendiğinde (SHIPPED durumundaki siparişe pay()) en iyi davranış hangisi?
Kendin gör
Sipariş durumu — boolean'lar mı, açık bir durum makinesi mi?
Tohum 692627- isPaid = false
- isShipped = false
- isDelivered = false
- isCancelled = false
- Oynat ya da adımla.
Şu an ne oldu?
Senaryo: pay() → ship() → deliver()
Üç boolean, sekiz olası kombinasyon.
Görevler0/3
Müşteriden iki kez para çekaçık
İpucu
Ödeme düğmesine iki kez basılırsa pay() bunu fark ediyor mu?
Hem kargoda hem iade edilmiş bir sipariş üretaçık
İpucu
cancel() teslimatı kontrol ediyor. Kargoyu?
Aynı hatalı senaryoyu geçersiz geçişi reddederek bitiraçık
İpucu
Mutlu yol dışındaki bir senaryoyu, izinli geçiş tablosu olan uygulamayla dene.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
- Varsayılanla oynat. Mutlu yolda iki uygulama da aynı sonucu veriyor.
- “Öde → öde” seç. Boolean’lı sürüm kartı iki kez çekiyor.
- “Öde → kargola → iptal et” seç. Hem kargoda hem iade edilmiş bir sipariş.
- Uygulamayı “State” yap. Aynı senaryolar, geçersiz adım olduğu yerde reddediliyor.
Kafam karıştı, daha basit anlat
Her durum hangi düğmelerin basılabileceğini bilir. Kargodaki bir siparişte “iptal” düğmesi hiç çalışmaz.
Kargodaki siparişler iptal edilip paraları iade ediliyor, paketler yine de müşteriye gidiyor. Hangi satır?
Satır satır: enum ile durum makinesi
Her durum için açık bir karar
public void cancel() { status = switch (status) { case NEW -> CANCELLED; case PAID -> { payments.refund(id); yield CANCELLED; } case SHIPPED, DELIVERED, CANCELLED -> throw new IllegalStateException(status + " durumunda iptal edilemez"); };}Debug
derleyici Switch bir ifade: bütün enum değerlerini kapsamak zorunda. default yok.
Sol/sağ ok tuşlarıyla da gezebilirsin.
Default dalı yazma. Yeni bir durum eklendiğinde ele alınmayan her yeri derleyici gösterir.
Durum makinesini Java'da enum ve switch ifadesiyle yazmanın, if-else zincirine göre asıl kazancı ne?
Zincir kur, isteği nesneye çevir
| Kalıp | Fikir | Tanıdık örnek |
|---|---|---|
| Chain of ResponsibilityBir isteği sıralı işleyicilerden geçirmek: her biri ya isteği karşılar ya da bir sonrakine iletir. Servlet filtreleri ve Spring Security filtre zinciri tipik örnek.Sözlükte gör → | Her halka ya karşılar ya sonrakine iletir | Servlet filtreleri, Spring Security filtre zinciri |
| CommandBir isteği, çalıştırılacak bir nesne olarak paketlemek. Böylece kuyruğa koyulabilir, ertelenebilir, yeniden denenebilir, loglanabilir ya da geri alınabilir.Sözlükte gör → | İstek, çalıştırılacak bir nesnedir | Runnable, kuyruktaki iş, geri al |
Zincirde sıra bir karardır. Rate limit kimlik doğrulamadan önce mi çalışmalı, sonra mı? Cevap sistemin davranışını değiştirir.
Command’ın değeri istek hemen çalışmadığında ortaya çıkar: kuyruğa koymak, yeniden denemek, kaydetmek, geri almak.
Bir FAST transferi gönderilmeden önce birkaç kontrolden geçer. Bu kontrolleri küçük bir zincir olarak kurunca her halka kısa kalıyor, sıra da tek bir yerde görünüyor.
Derinleş · FAST transferi: kontrol zinciri 4 dosya · ~68 satır · ilk okumada atlayabilirsin
Kafam karıştı, daha basit anlat
Zincir, bir isteğin sırayla geçtiği kontrol noktalarıdır. Command ise isteği bir kâğıda yazmaktır: kâğıdı kuyruğa koyabilir, sonra yeniden deneyebilirsin.
Spring Security'nin filtre zinciri hangi davranışsal kalıbın örneğidir?
Her ihtiyacı en uygun davranışsal kalıpla eşleştir.
Command kalıbının asıl değeri ne zaman ortaya çıkar?
Tuzaklar
İki durum için durum makinesi. Aktif/pasif için bir boolean yeter; kalıp üçüncü durumla gelir.
Kuralları servislere dağıtmak. Geçiş kuralı entity’nin kendi metodunda durmalı; beş serviste beş farklı kontrol olmamalı.
Sonu tanımsız zincir. Hiçbir halka karşılamazsa null dönen zincir, hatayı uzak bir yere taşır.
Eşzamanlı geçişler. Bellekteki durum makinesi doğru olsa da iki istek aynı anda geçiş yapabilir; veritabanında @Version gerekir.
Kendini sına
Üç boolean alan birlikte sekiz farklı kombinasyon üretir.
İki kullanıcı aynı anda aynı siparişi hem kargoya veriyor hem iptal ediyor. Nesnedeki durum makinesi doğru olsa bile ne ek gerekir?
Aklında kalacak üç şey
- 1 Üç boolean sekiz ihtimal üretir ve çoğu anlamsızdır. Durumu tek bir açık tip olarak tutmak geçersiz olanları yazılamaz kılar.
- 2 Chain of Responsibility'de her halka ya işi yapar ya bir sonrakine iletir. Sıra ve 'kimse yapmazsa ne olur?' sorusu açıkça cevaplanmalıdır.
- 3 Command isteği bir nesneye çevirir; böylece kuyruğa konabilir, yeniden denenebilir ya da geri alınabilir.
5 kart sonraki derste seni bekliyor