Kalıtım yerine Kompozisyon
Coddy'nin C# Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 41 / 70.
Kalıtım, sınıflar arasında sıkı bir bağımlılık oluşturur. Bir Car, Vehicle sınıfından kalıtım aldığında, Vehicle üzerinde yapılan herhangi bir değişiklik Car sınıfını bozabilir. Birleştirme daha esnek bir alternatif sunar: bir sınıf davranışı kalıtım yoluyla almak yerine, bu davranışı sağlayan nesneleri içerir.
Hareket edebilen ve saldırabilen bir oyun karakteri düşünün. Kalıtımla karmaşık bir hiyerarşi oluşturabilirsiniz. Bileşimle ise karaktere ihtiyaç duyduğu bileşenleri vermeniz yeterlidir:
public class MovementBehavior
{
public void Move() => Console.WriteLine("Moving...");
}
public class AttackBehavior
{
public void Attack() => Console.WriteLine("Attacking!");
}
public class Character
{
private MovementBehavior movement = new MovementBehavior();
private AttackBehavior attack = new AttackBehavior();
public void Move() => movement.Move();
public void Attack() => attack.Attack();
}Temel fark ilişkidir. Kalıtım "is-a" ilişkisini (bir Dog Animal'dır), bileşim ise "has-a" ilişkisini (bir Character hareket davranışına sahiptir) temsil eder. Bileşim, davranışları çalışma zamanında değiştirmenize, yetenekleri özgürce birleştirmenize ve kırılgan temel sınıf sorunundan kaçınmanıza olanak tanır.
Gerçek bir hiyerarşik ilişki olduğunda kalıtımı kullanın. Esnekliğe ihtiyaç duyduğunuzda, davranışlar birbiriyle ilgisiz sınıflar arasında paylaşılabildiğinde veya davranışı dinamik olarak değiştirmek istediğinizde bileşimi seçin.
Görev
KolayKalıtım yerine bileşimin gücünü gösteren bir bildirim sistemi oluşturalım. Karmaşık bir bildirim sınıfları hiyerarşisi oluşturmak yerine, değiştirilebilir davranış bileşenleri vererek bir NotificationSender oluşturacaksınız.
Kodunuzu üç dosyaya düzenleyeceksiniz:
Behaviors.cs: Bildirim gönderiminin farklı yönlerini ele alan iki davranış sınıfınıNotificationsad alanında oluşturun:FormattingBehavior- mesajın başınaFormat(string message)ve sonuna[ALERT]eklenmiş hâlini döndüren[END]metoduna sahiptirDeliveryBehavior-Deliver(string channel, string message)biçiminde bir dize döndürenSending via {channel}: {message}metoduna sahiptir
NotificationSender.cs: Davranışları birleştirmek için bileşimi kullanan birNotificationSendersınıfınıNotificationsad alanında oluşturun. Göndericiniz:- Özel alanlar olarak hem
FormattingBehaviorhem deDeliveryBehaviorörneklerini içermelidir - Gönderim kanalı adını depolayan bir
Channelözelliğine (string) sahip olmalıdır - Kanal adını kabul eden bir kurucuya sahip olmalıdır
- Önce biçimlendirme davranışını kullanarak mesajı biçimlendiren, ardından teslim davranışını kullanarak mesajı gönderen ve nihai sonucu döndüren bir
Send(string message)metoduna sahip olmalıdır
- Özel alanlar olarak hem
Program.cs: Ana dosyanızda, girdiden alınan bir kanalla birNotificationSenderoluşturun, ardından girdiden alınan bir mesajı gönderin. Bileşime dayalı davranışların birlikte nasıl çalıştığını göstermek için sonucu yazdırın.
İki girdi alacaksınız:
- Gönderim kanalı adı (ör.
Email,SMS) - Gönderilecek mesaj
Bildirim göndericiniz üzerinde Send() çağrısının sonucunu yazdırın.
Örneğin girdiler Email ve Server is down ise çıktı şu olmalıdır:
Sending via Email: [ALERT] Server is down [END]NotificationSender'ın herhangi bir sınıftan kalıtım almadığına dikkat edin; yalnızca biçimlendirme ve teslim davranışlarına "sahiptir". Bu bileşim yaklaşımı, gönderici sınıfını değiştirmeden davranışlardan herhangi birini kolayca değiştirmenize veya bu davranışları tamamen farklı sınıflarda yeniden kullanmanıza olanak tanır!
Kendin dene
using System;
using Notifications;
class Program
{
public static void Main(string[] args)
{
// Girdiyi oku
string channel = Console.ReadLine();
string message = Console.ReadLine();
// TODO: channel ile bir NotificationSender oluştur
// TODO: message'i gönder ve sonucu yazdı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 Dosyalarİsim Alanları ve YönergelerSınıf ve Nesnelere Giriş'this' Anahtar KelimesiMetotlar ve ParametrelerAlanlar ve ÖzelliklerYapıcı MetotlarNesne BaşlatıcılarÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (:) Sözdizimi'base' Anahtar KelimesiVirtual ve Override Anahtar KelimeleriSealed Sınıflar'object' Temel SınıfıÖzet - Çalışan Hiyerarşisi7İleri Düzey Özellikler
Operatör Aşırı Yüklemeİndeksleyiciler (this[])ToString() Geçersiz KılmaGenişletme MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişThread-Safe SingletonFactory KalıbıObserver Kalıbı (Olaylar)Strategy Kalıbı2Özellikler ve Statik Üyeler
Otomatik Uygulanan ÖzelliklerSadece Okunur/Yazılır ÖzelliklerStatik Alanlar ve MetotlarStatik Sınıflarİfade Gövdeli Üyeler5Polimorfizm ve Arayüzler
Derleme vs Çalışma Zamanı PolimorfizmiArayüz vs Soyut SınıfÇoklu ArayüzlerBelirgin ArayüzlerUpcasting ve DowncastingÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kalıtım yerine KompozisyonGenerics (Sınıflar ve Metotlar)Delegates ve EventlerAttributes ve ReflectionIDisposable ve using İfadesiDependency Injection Temelleri11Tasarı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ı3Sınıf Mimarisi
Örnek vs Statik Veri'readonly' ve 'const' Anahtar KelimeleriDestekleyici Alanlar (Backing Fields)Özet - Banka Hesabı Yöneticisi6Kapsülleme
Erişim BelirleyicilerKapsülleme için ÖzelliklerVeri Gizleme UygulamasıDeğişmezlik KalıplarıÖzet - Öğrenci KayıtlarıKendi başına pratik yap: Online C# derleyicisi