Bileşim
- İngilizcesi
- Composition
- Türkçe karşılığı
- kompozisyon
- Okunuşu
- kompızişın
Günlük kullanımda iki ad da yaygın.
Kısaca
Bileşim, bir nesneyi tuttuğu ve işi devrettiği başka nesnelerden kurar; bir üst sınıftan kalıtım almak yerine “sahiptir” (has-a) ilişkisini modeller.
Programlamada bileşim (composition) nedir?
Bileşim, bir sınıfı bir üst sınıfı genişleterek değil, başka nesnelerden kurmak demektir. Car, Engine sınıfından kalıtım almaz; bir alanda tuttuğu bir motora sahiptir ve start() metodu yalnızca o motordan çalışmasını ister. İşi bu şekilde elinizde tuttuğunuz bir nesneye devretmeye delegasyon (delegation) denir; ilişki de has-a, yani “sahiptir” ilişkisi olarak tanımlanır: bir arabanın motoru, bir sayfanın başlığı, bir siparişin kalemleri vardır.
Parçalar sıradan nesneler olduğu ve genellikle interface'lerin arkasında durduğu için değiştirilebilir. Bir araba, üretilirken hatta program çalışırken benzinli motor yerine elektrikli bir motor alabilir; bir test de ona sahte bir motor verebilir. Strategy, decorator ve dependency injection desenlerinin hepsi bu fikrin üzerine kuruludur. Bir heykeli tek bir bloktan oymak yerine LEGO parçalarıyla bir şey kurmaya benzer: her parça ayrı ve değiştirilebilir kalır.
“Sınıf kalıtımı yerine nesne bileşimini tercih edin” ilkesi, Dörtlü Çete (Gang of Four) olarak bilinen yazarların 1994 tarihli Design Patterns kitabından gelir. Kalıtım bir alt sınıfı üst sınıfının iç yapısına bağlar; bu yüzden üst sınıftaki bir değişiklik bütün alt sınıfları bozabilir ve özellikler birleştikçe hiyerarşiler çoğalır: ElectricCar, HybridCar, SelfDrivingElectricCar. Bazı diller tasarımları gereği bileşime yaslanır: Go'da sınıf kalıtımı yoktur, onun yerine bir struct başka bir struct'ın içine gömülür (embedding); Kotlin ise by anahtar sözcüğüyle bütün bir interface'i bir alana devredebilir.
Bileşim çoğunlukla kalıtımla karşılaştırılır ve belirleyici olan ilişkidir. Bir tür gerçekten başka bir türün bir çeşidiyse, tıpkı bir Dog nesnesinin bir Animal olması gibi, kalıtımı; bir şeye sahipse ya da bir şeyi kullanıyorsa bileşimi kullanın. Bileşim biraz daha fazla kod ister, çünkü işi devreden her metodun yazılması gerekir, ama sonuç daha kolay değiştirilir. Sözcüğün iki anlamı daha vardır: UML diyagramlarında bileşim, parçaların bütünle birlikte yaşayıp yok olduğu güçlü bir sahiplik ilişkisidir; fonksiyonel programlamada ise fonksiyon bileşimi (function composition), birinin çıktısı diğerine girecek şekilde fonksiyonları zincirler.
Önemli noktalar
- Bileşim, bir nesneyi tuttuğu ve işi devrettiği başka nesnelerden kurar.
- “Sahiptir” (has-a) ilişkisini modeller; kalıtım ise “-dir” (is-a) ilişkisini modeller.
- Interface'lerin arkasındaki parçalar değiştirilebilir; bu da kodu esnek ve kolay test edilir kılar.
- “Kalıtım yerine bileşim”, davranışı yeniden kullanırken önce bileşime başvurmak demektir.
- Go ve Kotlin bunu struct gömme ve
byanahtar sözcüğüyle doğrudan destekler.
Örnek
interface Engine { start(): string; }
class PetrolEngine implements Engine { start() { return "vroom"; } }
class ElectricEngine implements Engine { start() { return "hum"; } }
// A Car HAS an engine and delegates to it, so there is no need for
// PetrolCar, ElectricCar and HybridCar subclasses
class Car {
constructor(private engine: Engine) {}
start() { return `Car starting: ${this.engine.start()}`; }
}
new Car(new ElectricEngine()).start(); // "Car starting: hum"Sık sorulan sorular
“Kalıtım yerine bileşim” ne anlama gelir?
Bir tasarım kılavuzudur: bir davranışı yeniden kullanmak için, o davranışa sahip bir sınıfı genişletmek yerine onu sağlayan bir nesneyi tutmayı tercih edin. Kalıtım yasak değildir; gerçek “-dir” ilişkileri için saklanır.
Bileşim ile kümelenme (aggregation) arasındaki fark nedir?
İkisi de “sahiptir” ilişkisidir. UML'de bileşim, bütünün parçalarına sahip olduğu ve parçaların onunla birlikte yok edildiği anlamına gelir, tıpkı bir ev ve odaları gibi; kümelenme ise bir takım ve oyuncuları gibi parçaların kendi başlarına da var olabildiği anlamına gelir. Günlük kodda bileşim sözcüğü genellikle ikisini de kapsar.
Bileşim test yazmayı nasıl kolaylaştırır?
Parçalar genellikle dışarıdan, çoğu zaman yapıcı metot üzerinden gelir; böylece bir test, sınıfın kendisini değiştirmeden, örneğin gerçek veritabanı yerine bellek içi bir veritabanı gibi bir stub ya da fake verebilir.
İlgili sayfalar
- KalıtımProgramlamanın Temelleri, s. 34Kalı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.
- InterfaceProgramlamanın Temelleri, s. 29Interface, bir türün sağlamayı vaat ettiği metot ve özellik imzalarından oluşan adlandırılmış bir kümedir; bu üyelerin nasıl gerçekleştirildiğini söylemez.
- OOPProgramlamanın Temelleri, s. 46OOP, yani nesne yönelimli programlama, kodu ilişkili verileri onlar üzerinde işlem yapan fonksiyonlarla birleştiren nesneler etrafında düzenleme yöntemidir.
- Dependency InjectionYazılım Mimarisi, s. 11Dependency injection, bir nesnenin ihtiyaç duyduğu diğer nesneleri kendisi oluşturmak yerine dışarıdan almasını sağlayan bir tasarım tekniğidir.
- Strategy DeseniYazılım Mimarisi, s. 43Strategy deseni, değiştirilebilir algoritmaları tek arayüzün arkasına koyup çalışma zamanında aralarında geçiş yapılmasını sağlayan davranışsal bir desendir.
- Decorator PatternYazılım Mimarisi, s. 10Decorator pattern, bir nesneyi aynı arayüze sahip başka bir nesneyle sararak orijinal kodu değiştirmeden ona loglama, önbellekleme gibi davranışlar ekler.
Kaynaklar
Bu sayfada bir hata ya da eksik mi gördünüz?Düzeltme önerin