Tasarım Kalıpları — Ne Zaman Kazandırır
Önce şunu oku: Nesne Yönelimli Tasarım — Kapsülleme ve Kompozisyon
30 saniyede özet
Tasarım kalıpları icat edilmedi, fark edildi: farklı ekipler aynı soruna aynı çözümü bulunca ona bir ad verildi. Her kalıp bir şeyi ucuzlatır, başka bir şeyi pahalılaştırır.
Kalıp öğrenmenin en yaygın yan etkisi, her yerde uygulanacak yer aramaktır. Oysa kalıplar icat edilmedi — fark edildi. Farklı ekipler aynı probleme aynı çözümü bulunca ona bir ad verildi.
Adım adım oku
- Dar bir sokakta her evin üst katındaki oda küçük kalıyor.
- Birbirini tanımayan ustalar aynı çözümü buluyor: üst kat sokağa doğru taşıyor.
- Çözüm o kadar yaygınlaşıyor ki ona bir ad veriliyor: cumba.
- Artık iki kişi tek kelimeyle anlaşıyor. Tasarım kalıpları da böyle doğdu.
-
Bayt: Bütün tasarım kalıplarını ezberledim. Şimdi hepsini projeye koyacağım!
-
Sen: Hepsini mi? Neden?
-
Bayt: Kalıplar icat edilmedi, fark edildi. Önce sorun gelir, sonra çözüm, en son ad.
-
Bayt: Adı bilmenin asıl değeri tek kelimeyle anlaşmak. Kullanmak için bir sebep değil!
Kalıp sana iki şey verir
Bir kalıp sana iki şey verir: bir ad ve bir takas.
Ad, iletişim aracıdır. “Burada Strategy var” demek, karşı tarafa on satırlık açıklama yapmaya bedeldir — ama yalnızca o da adı biliyorsa.
Takas, asıl konudur. Hiçbir kalıp maliyeti yok etmez; bir yerden alıp başka yere koyar.
Strategy yeni tip eklemeyi ucuzlatır ve tüm tiplere yeni işlem eklemeyi pahalılaştırır. Bu, kalıbın kusuru değil, tanımıdır.
Kafam karıştı, daha basit anlat
Kalıp, sık yaşanan bir soruna verilmiş kısa bir addır. “Strategy” dediğinde karşındaki bütün fikri anlar, sen de uzun uzun anlatmak zorunda kalmazsın.
Bir tasarım kalıbı temelde nedir?
Strategy ile Factory arasındaki fark nedir?
Gerçekten işe yarayan birkaçı
Yirmi üç kalıbı ezberlemek gereksiz. Günlük işte tekrar tekrar karşına çıkan birkaçı var:
| Kalıp | Ne yapar | Ne zaman kazandırır |
|---|---|---|
| Strategy | Davranışı ayrı bir nesneye taşır | Aynı işin birden çok yapılış biçimi var ve yenisi ekleniyor |
| Decorator | Nesneyi aynı arayüzle sarmalar | Davranışı biriktirmek gerekiyor: cache + retry + log |
| Adapter | Uyuşmayan iki arayüzü bağlar | Dış kütüphanenin şekli senin modeline uymuyor |
| Facade | Karmaşık bir alt sistemi tek kapıya indirir | Çağıranın bilmesi gereken şey, var olan API’den az |
| Observer | Değişimi bilmesi gerekene haber verir | Yayıncının aboneleri tanımaması gerekiyor |
Adapter ile Facade sık karıştırılır: Adapter şekli değiştirir, Facade yüzeyi küçültür. Adapter’da karşı taraf zaten doğru işi yapıyordur, imzası uymuyordur; Facade’da işler doğrudur ama çağıranın görmesi gereken çok fazla şey vardır.
Kafam karıştı, daha basit anlat
Adapter bir priz dönüştürücüsüdür: fişin şeklini değiştirir. Facade ise tek düğmeli bir kumandadır: arkadaki karmaşık düğmeleri saklar.
Adapter ile Facade'ı ayıran şey nedir?
Satır satır: switch ne zaman Strategy’yi hak eder
Üç kanallı bir bildirim dağıtıcısında `switch`'i Strategy'ye çevirmek kaç dosya açılışını önler? Cevabı göster
Sıfır — Strategy tek başına hiçbir şey önlemez. Dağıtıcı hâlâ “hangi tip hangi sınıf” eşlemesini bildiği için yeni kanal yine bir dosya açtırır. Kazanç ancak eşlemeyi de dışarı çıkarınca gelir.
Kalıp maliyeti nereye taşıyor?
void send(Notification n) { switch (n.channel()) { case EMAIL -> email.send(n); case SMS -> sms.send(n); case PUSH -> push.send(n); }} // Strategy: davranış kendi dosyasındainterface Channel { void send(Notification n); } // ama dağıtıcı hâlâ eşlemeyi biliyorMap<Type, Channel> byType = Map.of(EMAIL, email, SMS, sms);Debug
bugün Üç kanal, tek dosya. Akışı izlemek için tek yere bakıyorsun — bu gerçek bir avantaj, kusur değil.
- dosya
- = 1
- okuma
- = 1 yer
Sol/sağ ok tuşlarıyla da gezebilirsin.
Bu takasın adı expression problemBir tasarımın ya yeni tip eklemeyi ya yeni işlem eklemeyi ucuzlatabilmesi, ikisini birden ucuzlatamaması.Polimorfizm yeni tipi ucuzlatır: yeni sınıf yazarsın, çağıran değişmez. switch ise yeni işlemi ucuzlatır: tek yerde tüm tipleri ele alırsın. Hangisinin daha sık olacağını bilmek, kalıp kararını verir.Sözlükte gör →: polimorfizm yeni tip eklemeyi ucuzlatır, switch yeni işlem eklemeyi. İkisini birden ucuzlatan bir tasarım yok.
Bir bankada para gönderirken de aynı soru çıkar: FAST mı, EFT mi, SWIFT mi? Gel, her kanalın kendi dosyasında yaşadığı küçük bir örneğe bakalım.
Derinleş · Havale kanalları: Strategy ve registry 4 dosya · ~77 satır · ilk okumada atlayabilirsin
Bir `switch`'i Strategy'ye çevirdin ama yeni tip eklemek hâlâ var olan bir dosyayı açtırıyor. Neden?
Her ihtiyacı, çözümü sarmalamak mı yoksa davranışı ayırmak mı olduğuna göre ayır.
Kendin gör
Aynı dağıtıcı, dört tasarım
Tohum 7- Tek switch
- Strategy
- Kendini kaydeden registry
- Kalıp yığını
Tek dosyada bir switch, üç dal.
- Dosya
- 1
- Yeni kanal açtırıyor
- 1 dosya
- Yeni işlem açtırıyor
- 1 dosya
- Akışı izlemek için
- 1 yer
| Tasarım | Açılan dosya | Okuma |
|---|---|---|
| Tek switch | 14 | 1 |
| Strategy | 20 | 3 |
| Kendini kaydeden registryen ucuz | 8 | 3 |
| Kalıp yığını | 18 | 7 |
Şu an ne oldu?
Tek dosya, tek switch
Her yeni kanal bu çalışan, test edilmiş dosyayı açtırıyor — beklenen karışımda toplam 14 dosya açılışı. Ama akışı izlemek için tek yere bakıyorsun. Bu karışımda Kendini kaydeden registry daha ucuz (8 dosya).
Aklında kalsın: Üç sabit tip için switch bir kusur değil. Maliyet, dosyanın ne sıklıkta yeniden açıldığında doğar.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
Sırayla dene:
- Başlangıçta tek
switchvar. “Eklenecek yeni kanal”ı 2’ye indir — en ucuz tasarım hangisi? - Kanalı 12’ye çıkar. Şimdi registry kazanıyor: kalıp kendini ödemeye başladığı nokta burası.
- Kanalı 12’de bırakıp “yeni işlem”i 8’e çıkar. Kazanan yine
switch— expression problem’i sayılarla görüyorsun. - “Kalıp yığ”a bas ve tabloyu incele: hiçbir karışımda kazanmıyor. Bir kalıp takas yapmıyorsa sadece dolaylılıkBir şeye doğrudan değil, araya giren bir katman üzerinden ulaşmak. Esneklik verir, okurken bir adım daha attırır — bedava değildir.Sözlükte gör → ekliyor demektir.
Tuzaklar
Singleton. Kalıp listesindeki en popüler ve en zararlı madde: global durum yaratır, testte izole edilemez, bağımlılığı imzada gizler.
Bugün ihtiyacın olan şey neredeyse her zaman “tek örnek”tir, “global erişim” değil — onu da DI container zaten veriyor.
Kalıp önce, problem sonra. Tasarıma “hangi kalıbı kullansam” diye başlamak, çözümü probleme uydurmaktır. Doğru sıra: değişim nereden gelecek, sonra hangi takas.
İsimlendirme kargaşası. OrderStrategyFactoryImpl gibi adlar kalıbı anlatır ama işi anlatmaz. Sınıf adı ne yaptığını söylemeli; kalıbın adı gerekiyorsa yorumda durabilir.
Kafam karıştı, daha basit anlat
Singleton’ın asıl sorunu tek olması değil, herkesin her yerden ona ulaşabilmesidir. Tek bir örnek istiyorsan bunu Spring’e bırak, o zaten tek tane kurar.
Kendini sına
Tasarım kalıpları, kullanılsın diye önceden icat edilmiş kurallardır.
Bu program ne yazdırır?
Aklında kalacak üç şey
- 1 Bir kalıp maliyeti yok etmez, yerini değiştirir. Strategy yeni tip eklemeyi ucuzlatır, bütün tiplere yeni işlem eklemeyi pahalılaştırır.
- 2 Kalıbın adını bilmek onu kullanmak için sebep değildir. Sebep her zaman, değişikliğin hangi yönden geleceğidir.
- 3 Kalıp isimlerinin asıl değeri anlaşmaktır: 'burada Strategy var' demek on satır açıklamanın yerini tutar.
5 kart sonraki derste seni bekliyor
Bu dersin üstüne kurulanlar
Bunlar bu dersi temel alıyor; hazır olduğunda devam edebilirsin.
- Tasarım & Temiz KodSpring'in İçindeki Kalıplar — Strategy, Template Method, Proxy, ObserverBir olay dinleyicisi, kayıt veritabanına yazılmadan önce mi çalışır, sonra mı?Derse git
- Tasarım & Temiz KodYapısal Kalıplar — Sarmalayarak GenişletmekBir nesnenin koduna dokunmadan ona yeni bir davranış nasıl eklersin?Derse git
- Tasarım & Temiz KodDavranışsal Kalıplar — State, Chain of Responsibility, CommandÜç ayrı true/false alanı, kaç tane anlamsız durum yaratır?Derse git