Sitemap

Composite Design Pattern

3 min readJan 29, 2026

--

Bir e-ticaret sitesinin kategori ağacını, bilgisayarınızdaki dosya sistemini veya bir şirketin organizasyon şemasını kodladığınızı hayal edin. Ortak nokta nedir? Hepsi hiyerarşik ve ağaç (tree) yapısındadır.

Bir klasörün içinde dosyalar olabilir, ama başka klasörler de olabilir. O klasörlerin içinde de yine dosyalar ve klasörler… Bu iç içe geçmiş (recursive) yapıyı yönetmek, eğer doğru tasarımı kullanmazsanız tam bir if-else ve tür kontrolü (type casting) cehennemine dönüşebilir.

İşte tam bu noktada, Yapısal (Structural) tasarım kalıplarının kahramanlarından Composite Design Pattern devreye giriyor.

Composite Pattern Nedir?

Composite Pattern, nesneleri ağaç yapısında düzenlemenizi ve bu yapıdaki tekil nesneler (Leaf) ile nesne gruplarını (Composite) aynı şekilde yönetmenizi sağlar.

Basitçe söylemek gerekirse: İstemci (Client), karşısındaki nesnenin tek bir parça mı yoksa parçalardan oluşan bir kutu mu olduğunu bilmek zorunda kalmaz. İkisine de aynı komutu verir.

Gerçek Hayat Analojisi: Dosya Sistemi

İşletim sisteminizde bir dosyaya “çift tıklamak” ile bir klasöre “çift tıklamak” aslında aynı arayüz eylemidir (Aç).

  • Eğer bir Dosya (Leaf) ise, ilgili programla açılır.
  • Eğer bir Klasör (Composite) ise, içeriği listelenir (ve içindeki her şeye de tıklanabilir).

Siz (Client), tıkladığınız şeyin karmaşıklığıyla ilgilenmezsiniz. Sadece “Aç” dersiniz.

Yapının Anatomisi

Bu kalıp 3 temel aktörden oluşur:

  1. Component (Bileşen): Ağaçtaki tüm nesneler (yapraklar ve dallar) için ortak arayüzü tanımlar. İstemcinin iletişim kurduğu yer burasıdır.
  2. Leaf (Yaprak): Alt öğesi olmayan, en uçtaki nesnedir. İşin asıl yapıldığı yerdir.
  3. Composite (Bileşik): Altında başka Leaf veya Composite nesneleri barındıran yapıdır. Kendisine gelen isteği çocuklarına iletmekle (delegation) sorumludur.
  1. Component (Arayüz)

Önce Ortak bir dil oluşturuyoruz


public interface OrderComponent {
double calculatePrice();
}

2. Leaf (Tekil Ürün)

En basit yapı birimi. Fiyatı kendisi bilir.


public class Product implements OrderComponent {
private String name;
private double price;

public Product(String name, double price) {
this.name = name;
this.price = price;
}

@Override
public double calculatePrice() {
return this.price;
}
}

3. Composite (Kutu/Paket)

Get Muratguven’s stories in your inbox

Join Medium for free to get updates from this writer.

İçinde çocukları barındıran yapı. Fiyat sorulduğunda, içindeki herkesin fiyatını toplayıp döner.

import java.util.ArrayList;
import java.util.List;

public class Box implements OrderComponent {
private List<OrderComponent> items = new ArrayList<>();

public void add(OrderComponent item) {
items.add(item);
}

public void remove(OrderComponent item) {
items.remove(item);
}

@Override
public double calculatePrice() {
double total = 0;
for (OrderComponent item : items) {
total += item.calculatePrice();
}
return total;
}
}
public class Main {
public static void main(String[] args) {

Product phone = new Product("iPhone 15", 50000);
Product charger = new Product("Charger", 1000);
Product headset = new Product("AirPods", 5000);

Box accessoryBox = new Box();
accessoryBox.add(charger);
accessoryBox.add(headset);

Box bigShipment = new Box();
bigShipment.add(phone);
bigShipment.add(accessoryBox);


System.out.println("Toplam Tutar: " + bigShipment.calculatePrice());
}
}

Tasarım İkilemi (Trade-off)

Composite pattern uygularken mimarların en çok tartıştığı konu şudur: Şeffaflık mı (Transparency), Güvenlik mi (Safety)?

Çocuk ekleme/çıkarma metodlarını (add, remove) nereye koymalıyız?

1. Şeffaflık (Transparency) Yaklaşımı

Metodları en tepeye, Component arayüzüne koyarsınız.

  • Artısı: İstemci, elindeki nesnenin Leaf mi yoksa Composite mi olduğunu asla bilmek zorunda kalmaz. Her şeye add() diyebilir. Polimorfizm tam anlamıyla kullanılır.
  • Eksisi: Leaf (Yaprak) nesnesine add() derseniz ne olur? Anlamsızdır. Genellikle çalışma zamanında (Runtime) hata fırlatmak zorunda kalırsınız. Güvenlikten ödün vermiş olursunuz.

2. Güvenlik (Safety) Yaklaşımı

Metodları (add, remove) sadece Composite sınıfına koyarsınız.

  • Artısı: Leaf nesnesine yanlışlıkla çocuk eklemeye çalışamazsınız. Derleme zamanında (Compile time) hata alırsınız. Daha güvenlidir.
  • Eksisi: İstemci, elindeki Component’e çocuk eklemek istediğinde onun Composite tipinde olup olmadığını kontrol etmek (type check) ve cast etmek zorunda kalır. Bu da deseni biraz bozar.

Hangi yolu seçmeliyim? Genellikle, kodun esnekliğini ve istemcinin basitliğini korumak adına Transparency tercih edilir, ancak Leaf nesnelerinde metodların “desteklenmeyen işlem” hatası döndürmesi kabul edilir.

Ne Zaman Kullanmalısınız?

  • Nesnelerin “Parça-Bütün” (Part-Whole) hiyerarşisini temsil etmeniz gerekiyorsa.
  • İstemcilerin, tekil nesneler ile nesne grupları arasındaki farkı bilmesini istemiyorsanız.

Avantaj ve Dezavantajlar

Avantajları:

  • Karmaşıklığı Gizler: İstemci kodu çok basitleşir. Döngüler ve if-else blokları azalır.
  • Open/Closed Prensibi: Sisteme yeni bileşen türleri (yeni bir Leaf veya yeni bir Composite) eklemek kolaydır, mevcut kodu bozmaz.

Dezavantajları:

  • Kısıtlama Zorluğu: Composite sınıfının içine “sadece şu tip nesneler eklensin” demek zordur. Tür sistemi (Type system) yerine çalışma zamanı kontrolleri yapmanız gerekebilir.

Sonuç

Composite Design Pattern, hiyerarşik verilerin karmaşıklığını yönetmek için zarif bir çözümdür. Özyinelemeyi (recursion) polimorfizm ile birleştirerek, en karmaşık ağaç yapılarını bile tek bir metod çağrısıyla yönetilebilir hale getirir.

--

--