Dekoratör Kalıbı
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 72 / 87.
Decorator Kalıbı, nesneleri dekoratör adı verilen özel nesnelerle sarmalayarak onlara yeni davranışlar eklemenizi sağlayan yapısal bir tasarım kalıbıdır. Derleme zamanında davranış ekleyen kalıtımdan farklı olarak dekoratörler, özgün sınıfı değiştirmeden çalışma zamanında işlevselliği dinamik olarak ekler.
Temel bir kahveyle başlayıp süt, şeker veya krem şanti gibi ekstralar ekleyebildiğin bir kahve dükkânı hayal et. Her ekleme, orijinal kahveyi sararak kendi maliyetini ve açıklamasını ekler. Bu desen, süslenmiş nesnelere orijinaliyle aynı şekilde davranılabilmesini sağlamak için ortak bir arayüz kullanır:
interface Coffee {
String getDescription();
double getCost();
}
class SimpleCoffee implements Coffee {
public String getDescription() {
return "Simple Coffee";
}
public double getCost() {
return 2.0;
}
}
abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
}
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
public String getDescription() {
return coffee.getDescription() + ", Milk";
}
public double getCost() {
return coffee.getCost() + 0.5;
}
}Dekoratör, sarılmış nesneye bir referans tutar ve kendi davranışını eklerken çağrıları ona devreder. Özellikleri birleştirmek için birden fazla dekoratörü üst üste kullanabilirsiniz:
Coffee order = new SimpleCoffee();
order = new MilkDecorator(order);
order = new SugarDecorator(order);
System.out.println(order.getDescription()); // Sade Kahve, Süt, Şeker
System.out.println(order.getCost()); // 2.75Decorator Pattern, alt sınıflarda bir patlama yaratmadan nesnelere sorumluluklar eklemeniz gerektiğinde öne çıkar. Her dekoratör bağımsızdır; bu nedenle ihtiyaç duyduğunuz davranışların tam birleşimini oluşturmak için bunları özgürce bir araya getirip eşleştirebilirsiniz.
Görev
KolayDecorator Pattern kullanarak bir bildirim sistemi oluşturalım! Birbirlerinin etrafına decorator'lar sararak farklı teslim kanalları, e-posta uyarıları, SMS uyarıları ve push bildirimleriyle geliştirilebilen temel bir bildirim oluşturacaksın. Bu, tek bir mesajın aynı anda birden fazla kanal üzerinden gönderilmesi gerekebilen gerçek dünya sistemlerini yansıtır.
Kodunu dört dosya arasında düzenleyeceksin:
Notifier.java: Decorator Pattern'in bileşen arayüzü olarak görev yapanNotifierarayüzünü Define et. Bildirimleri göndermeyi yönetensend(String message)metodunu Declare etmelidir.BasicNotifier.java:Notifierarayüzünü Implement eden concrete bileşen sınıfını Create et. Bu, en basit bildirim biçimini, uygulama içi bir uyarıyı temsil eder.sendçağrıldığındaIn-App: [message]yazdırmalıdır.NotifierDecorators.java: Decorator hiyerarşini burada oluştur.Notifierarayüzünü Implement eden ve constructor'ı aracılığıyla kendisine iletilen sarılmış birNotifiernesnesine referans tutan abstract birNotifierDecoratorsınıfıyla başla.Ardından
NotifierDecoratorsınıfını genişleten üç concrete decorator Create et:EmailDecorator-sendçağrıldığında önce sarılmış notifier'a delege eder, ardındanEmail: [message]yazdırır.SMSDecorator-sendçağrıldığında önce sarılmış notifier'a delege eder, ardındanSMS: [message]yazdırır.PushDecorator-sendçağrıldığında önce sarılmış notifier'a delege eder, ardındanPush: [message]yazdırır.Main.java: Decorator sistemini bir araya getir! İki girdi alacaksın: bildirim mesajı (String) ve eklenecek kanalların virgülle ayrılmış listesi (String); örneğin"email,sms"veya"push,email,sms".Bir
BasicNotifierile başla. Ardından channels input'una göre onu, göründükleri sırayla uygun decorator'larla sar. Geçerli kanal adlarıemail,smsvepush'tur.Son olarak, fully decorated notifier üzerinde mesajınla birlikte
sendçağrısı yap.
İki girdiyi sırayla alacaksın: gönderilecek mesaj (String) ve etkinleştirilecek kanallar (virgülle ayrılmış String).
Örneğin, Server is down! ve email,push girdileriyle çıktın şöyle olur:
In-App: Server is down!
Email: Server is down!
Push: Server is down!Her decorator'ın, özgün bildirimi korurken kendi davranışını nasıl eklediğine dikkat et. Sarma sırası, çıktının sırasını belirler: en içteki bileşen (BasicNotifier) önce çalışır, ardından her decorator kendi katmanını ekler. Her kombinasyon için ayrı sınıflar oluşturmadan kanalların herhangi bir kombinasyonunu bir araya getirip kullanabilirsin!
Kendin dene
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Gönderilecek mesajı oku
String message = scanner.nextLine();
// Kanalların virgülle ayrılmış listesini oku (örn., "email,sms" veya "push,email,sms")
String channelsInput = scanner.nextLine();
// TODO: BasicNotifier ile başla
// TODO: Kanallar girişini virgülle ayır
// TODO: Her kanal için döngü yap ve notifier'ı uygun decorator ile sar
// Geçerli kanallar: "email", "sms", "push"
// TODO: Tamamen dekore edilmiş notifier üzerinde mesaj ile send'i çağır
}
}
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ıKendi başına pratik yap: Online Java derleyicisi