Dekoratör Kalıbı
Coddy'nin Dart Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 96 / 110.
Decorator deseni, nesneleri dekoratör adı verilen özel nesnelerle sarmalayarak onlara dinamik olarak yeni davranışlar eklemenize olanak tanır. Derleme zamanında davranış ekleyen kalıtımın aksine, dekoratörler orijinal sınıfı değiştirmeden çalışma zamanında ek sorumluluklar yükler.
Temel fikir, hem orijinal nesnenin hem de dekoratörlerin aynı arayüzü uygulamasıdır.
Bir dekoratör orijinal nesneyi sarmalar, ona delege eder ve öncesinde veya sonrasında kendi davranışını ekler:
abstract class Coffee {
String getDescription();
double getCost();
}
class SimpleCoffee implements Coffee {
@override
String getDescription() => 'Simple Coffee';
@override
double getCost() => 2.0;
}
class MilkDecorator implements Coffee {
final Coffee _coffee;
MilkDecorator(this._coffee);
@override
String getDescription() => '${_coffee.getDescription()}, Milk';
@override
double getCost() => _coffee.getCost() + 0.5;
}
class SugarDecorator implements Coffee {
final Coffee _coffee;
SugarDecorator(this._coffee);
@override
String getDescription() => '${_coffee.getDescription()}, Sugar';
@override
double getCost() => _coffee.getCost() + 0.2;
}
void main() {
Coffee coffee = SimpleCoffee();
coffee = MilkDecorator(coffee);
coffee = SugarDecorator(coffee);
print(coffee.getDescription()); // Simple Coffee, Milk, Sugar
print(coffee.getCost()); // 2.7
}Her dekoratör, bir önceki nesneyi sarmalar ve onu geliştirir. Her olası kombinasyon için bir alt sınıf (subclass) oluşturmadan esnek bir davranış yaratarak, birden fazla dekoratörü herhangi bir kombinasyonda üst üste ekleyebilirsiniz. Bu desen, aynı sınıfa ait diğer nesneleri etkilemeden nesnelere özellikler eklemeniz gerektiğinde idealdir.
Görev
KolayDecorator desenini kullanarak bir pizza sipariş sistemi oluşturalım! Her bir malzemenin bir önceki öğeyi sarmaladığı ve hem açıklamaya hem de fiyata ekleme yaptığı, çeşitli malzemelerle geliştirilebilen temel bir pizza oluşturacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
pizza.dart: Bu dosya pizza arayüzünüzü ve tüm dekoratör sınıflarını içerir. İki yöntem tanımlayan birPizzasoyut sınıfı ile başlayın:String getDescription()vedouble getPrice(). ArdındanPizzaarayüzünü uygulayan birPlainPizzasınıfı oluşturun - bu sınıf açıklama olarakPlain Pizzadöndürür ve maliyeti8.0'dır. Şimdi her biri birPizzanesnesini sarmalayan ve onu geliştiren üç dekoratör sınıfı oluşturun:CheeseDecorator- açıklamaya, Cheeseve fiyata1.5eklerPepperoniDecorator- açıklamaya, Pepperonive fiyata2.0eklerMushroomDecorator- açıklamaya, Mushroomsve fiyata1.25ekler
Pizzaarayüzünü uygulamalı, yapıcı metodunda (constructor) birPizzakabul etmeli ve kendi katkısını eklemeden önce sarmalanmış pizzaya delege etmelidir.main.dart: Pizza dosyanızı içe aktarın ve dekoratörlerin özelleştirilmiş bir sipariş oluşturmak için nasıl üst üste bindiğini gösterin. BirPlainPizzaile başlayın, ardından onuCheeseDecoratorile sarmalayın, sonra bunuPepperoniDecoratorile sarmalayın ve son olarak her şeyiMushroomDecoratorile sarmalayın. Nihai pizzanın açıklamasını yazdırın, ardındanTotal: $ve sonrasında fiyatı yazdırın.
Her dekoratörün bir öncekinin üzerine nasıl inşa edildiğine dikkat edin - basit, tek sorumluluklu dekoratörleri üst üste koyarak tam donanımlı bir pizza oluşturuyorsunuz!
Beklenen çıktı:
Plain Pizza, Cheese, Pepperoni, Mushrooms
Total: $12.75Kopya kağıdı
Decorator deseni, nesneleri dekoratör nesneleriyle sarmalayarak onlara dinamik olarak yeni davranışlar ekler. Hem orijinal nesne hem de dekoratörler aynı arayüzü uygular.
Temel bileşenler:
- Ortak metotları tanımlayan soyut bir sınıf veya arayüz
- Temel işlevselliği uygulayan somut bir sınıf
- Orijinal nesneyi sarmalayan ve onu geliştiren dekoratör sınıfları
Her dekoratör:
- Dekore ettiği nesneyle aynı arayüzü uygular
- Sarmalanmış nesneye bir referans tutar
- Çağrıları sarmalanmış nesneye iletir
- İletimden önce veya sonra kendi davranışını ekler
abstract class Coffee {
String getDescription();
double getCost();
}
class SimpleCoffee implements Coffee {
@override
String getDescription() => 'Simple Coffee';
@override
double getCost() => 2.0;
}
class MilkDecorator implements Coffee {
final Coffee _coffee;
MilkDecorator(this._coffee);
@override
String getDescription() => '${_coffee.getDescription()}, Milk';
@override
double getCost() => _coffee.getCost() + 0.5;
}
// Birden fazla dekoratörü üst üste ekleyin
Coffee coffee = SimpleCoffee();
coffee = MilkDecorator(coffee);
coffee = SugarDecorator(coffee);Dekoratörler herhangi bir kombinasyonda üst üste eklenebilir, bu da her olası kombinasyon için alt sınıflar oluşturmaya gerek kalmadan esnek bir davranış sağlar.
Kendin dene
import 'pizza.dart';
void main() {
// TODO: Bir PlainPizza oluşturun
// TODO: Onu CheeseDecorator ile sarmalayın
// TODO: Onu PepperoniDecorator ile sarmalayın
// TODO: Her şeyi MushroomDecorator ile sarmalayın
// TODO: Nihai pizzanın açıklamasını yazdırın
// TODO: "Total: $" ve ardından fiyatı yazdırın
}
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 DosyalarKütüphaneler ve ImportlarOOP'ye GirişSınıflar ve Nesnelerthis Anahtar KelimesiMetotlarÖrnek DeğişkenleriConstructor TemelleriÖzet - Basit Hesap Makinesi4Null Safety
Null Safety'ye GirişNullable ve Non-Nullable? ve ! OperatörleriLate Anahtar Kelimesi ve Null SafetyNull-Aware OperatörleriSınıflarda Null SafetyÖzet - Kullanıcı Profili Sistemi7Soyut Sınıflar ve Arayüzler
Soyut SınıflarSoyut MetotlarDart'ta ArayüzlerÖrtük ArayüzlerUygulama vs. GenişletmeÇoklu ArayüzlerÖzet - Şekil Hesaplayıcı10Koleksiyonlar ve Generic'ler
List, Set, Map Genel BakışTip Güvenli KoleksiyonlarGeneric SınıflarGeneric MetotlarGeneric KısıtlamalarIterable ve IteratorÖzet - Generic Depolama2Dart'ta Yapıcılar
Varsayılan Yapıcıİsimlendirilmiş Yapıcılarİlklendirme ListeleriSabit YapıcılarFabrika YapıcılarıYönlendiren YapıcılarÖzet - Şekil Oluşturucu5Kapsülleme
Public ve Private Üyeler_ Öneki KuralıKütüphane Düzeyinde GizlilikGetter ve Setter DetaylarıBilgi GizlemeÖzet - Öğrenci Kayıtları8Mixin'ler
Mixin'lere GirişMixin OluşturmaBirden Fazla Mixin KullanımıMixin'lerde on Anahtar KelimesiMixin vs KalıtımMixin vs ArayüzÖzet - Hayvan Sistemi11Özel Metotlar
toString() OverridehashCode ve == OverrideComparable Arayüzücall() MetodunoSuchMethod OverrideÖzet - Özel Koleksiyon14Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı17Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakter SistemiAraç Kiralama Servisi3Sınıf Özellikleri
Instance ve Statik ÜyelerFinal ve Const AlanlarLate DeğişkenlerStatik Metotlar ve AlanlarGetters ve SettersÖzet - Banka Hesabı Yöneticisi6Kalıtım
Temel Kalıtımsuper Anahtar KelimesiMetot Ezme@override Anotasyonufinal Sınıf Anahtar KelimesiYapıcı Metotlar ve KalıtımÖzet - Çalışan Hiyerarşisi9Çok Biçimlilik
Çok Biçimlilik TemelleriInterface'ler ile Çok BiçimlilikÇalışma Zamanı Tip Kontrolüis ve as OperatörleriCovariant Anahtar KelimesiÖzet - Ödeme İşlemcisi12Asenkron OOP
Futures ve async/awaitStream TemelleriStream Controller'larAsenkron KurucularSınıf Metotlarında Asenkron KullanımıÖzet - Data Fetcher15Tasarı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ıRepository Kalıbı