Decorator Pattern
Dekoratör Kalıbı
- Okunuşu
- dekıreytır petırn
Kısaca
Decorator pattern, bir nesneyi aynı arayüze sahip başka bir nesneyle sararak orijinal kodu değiştirmeden ona loglama, önbellekleme gibi davranışlar ekler.
Decorator pattern nedir?
Dosya okuyup yazan bir DataSource'unuz olduğunu ve seçenek olarak sıkıştırma ve şifreleme istediğinizi düşünün. Her kombinasyon için alt sınıflar hızla çoğalır. Dekoratörlerle EncryptedSource ve CompressedSource herhangi bir DataSource'u sarar, kendi ek işlerini yapar ve çağrıları içerideki nesneye iletir. Onları istediğiniz sırayla üst üste koyabilirsiniz: new EncryptedSource(new CompressedSource(new FileSource(path))).
1994'te Gang of Four kitabında tarif edilen ilk tasarım kalıplarından biridir. Her dekoratör sardığı nesneyle aynı arayüze sahip olduğu için çağıranlar farkı göremez; bu da açık/kapalı ilkesini izler: davranış mevcut sınıflar düzenlenerek değil, yeni sınıflar eklenerek genişletilir. FileInputStream'i saran BufferedInputStream gibi Java'nın I/O akışları klasik bir örnektir.
Aynı fikir birçok biçimde karşımıza çıkar. Web middleware'i bir istek işleyicisini loglama, kimlik doğrulama ve hata yönetimiyle sarar; HTTP istemcileri taşıma katmanlarını yeniden denemeler ve önbelleklemeyle sarar; yüksek mertebeden fonksiyonlar da zamanlama ya da memoization eklemek için bir fonksiyonu sarar. Python'un @decorator sözdizimi ve TypeScript dekoratörleri bu sarma fikri üzerine kurulmuş dil özellikleridir, ama tek tek nesneleri değil fonksiyonları ve sınıfları süslerler.
Sık yapılan bir yanlış, dekoratörlerin bedava olduğunu düşünmektir. Çok sayıda sarma katmanı stack trace'leri uzatır ve davranışı izlemeyi zorlaştırır; sıra da önemlidir: kimlik doğrulamadan önce ya da sonra önbelleklemek çok farklı sonuçlar verir. Her dekoratörü küçük ve odaklı tutun ve sarma sırasını tek bir yerde açıkça belirtin.
Önemli noktalar
- Dekoratör bir nesneyi aynı arayüzle sarar ve davranış ekler.
- Dekoratörler istenen her kombinasyonda ve sırada üst üste konabilir.
- Mevcut sınıfları düzenlemeden davranışı genişletir.
- Middleware, akış sarmalayıcıları ve yüksek mertebeden fonksiyonlar bu fikri kullanır.
- Sarma sırası önemlidir ve derin yığınların hatasını ayıklamak daha zordur.
Örnek
interface PriceService {
getPrice(productId: string): Promise<number>;
}
class ApiPriceService implements PriceService {
async getPrice(id: string) { return fetchPriceFromApi(id); }
}
class CachedPrices implements PriceService {
private cache = new Map<string, number>();
constructor(private inner: PriceService) {}
async getPrice(id: string) {
if (!this.cache.has(id)) this.cache.set(id, await this.inner.getPrice(id));
return this.cache.get(id)!;
}
}
class LoggedPrices implements PriceService {
constructor(private inner: PriceService) {}
async getPrice(id: string) {
console.time(id);
try { return await this.inner.getPrice(id); } finally { console.timeEnd(id); }
}
}
// Same interface, extra behavior layered on
const prices: PriceService = new LoggedPrices(new CachedPrices(new ApiPriceService()));Sık sorulan sorular
Decorator pattern ile kalıtım arasındaki fark nedir?
Kalıtım, alt sınıflar oluşturarak derleme zamanında davranış ekler ve kombinasyonların her biri için bir sınıf gerekir. Dekoratörler ise nesneleri sararak çalışma zamanında davranış ekler; böylece özellikler her kombinasyon için bir sınıfa gerek kalmadan serbestçe birleştirilebilir.
Python dekoratörleri decorator pattern mi?
Birbiriyle ilişkilidir ama aynı değildir. Python'un @ sözdizimi fonksiyonları ya da sınıfları başka bir fonksiyonla saran, aynı fikirden esinlenmiş bir dil özelliğidir. Tasarım kalıbı ise bir arayüzü paylaşan nesneleri sarar.
Decorator ile adapter arasındaki fark nedir?
Decorator aynı arayüzü korur ve davranış ekler. Adapter ise bir nesnenin farklı bir arayüz beklenen yerde kullanılabilmesi için arayüzü değiştirir.
İlgili sayfalar
- Tasarım DeseniYazılım Mimarisi, s. 42Tasarım deseni, yazılım tasarımında sık görülen bir soruna kanıtlanmış, yeniden kullanılabilir çözümdür; hazır kod değil, genel bir şablon olarak anlatılır.
- Adapter DeseniYazılım Mimarisi, s. 1Adapter deseni, mevcut bir sınıfı yeni bir arayüzle sararak bir arayüz bekleyen kodun uyumsuz bir arayüzü kullanabilmesini sağlayan yapısal tasarım desenidir.
- MiddlewareBackend ve API'ler, s. 29Middleware, bir sistemin iki katmanı arasında duran yazılımdır; bir web sunucusunda çoğunlukla gelen istek ile son yanıt arasında çalışan koddur.
- Yüksek dereceli fonksiyonProgramlamanın Temelleri, s. 56Yüksek dereceli fonksiyon, başka bir fonksiyonu argüman olarak alan, fonksiyon döndüren ya da ikisini de yapan fonksiyondur; davranış veri gibi taşınabilir.
- KalıtımProgramlamanın Temelleri, s. 31Kalıtım, yeni bir sınıfın mevcut bir sınıfın alanlarını ve metotlarını yeniden kullanmasını, genişletmesini ve geçersiz kılmasını sağlayan OOP özelliğidir.
- SOLIDYazılım Mimarisi, s. 39SOLID, geliştiricilerin daha anlaşılır, genişletilebilir, test edilebilir ve bakımı kolay kod yazmasına yardım eden beş nesne yönelimli tasarım ilkesidir.
Bu sayfada bir hata ya da eksik mi gördünüz?Düzeltme önerin