Structural — Yapısal Desenler

Composite

Bileşik Nesne Deseni

Amaç: Nesneleri ağaç yapısında bir araya getirmek ve istemcinin tekil nesnelere de nesne gruplarına da aynı şekilde davranabilmesini sağlamak.

1

Basit Anlatım

Teknik terim yok — günlük hayattan bir benzetme

Bilgisayarınızdaki klasörleri düşünün. Bir klasörün içinde dosyalar olabilir, ama başka klasörler de olabilir; onların içinde de dosyalar ve klasörler…

Bir klasörün boyutunu sorduğunuzda bilgisayar ne yapar? İçindeki her şeyin boyutunu toplar. İçerideki şey bir dosyaysa boyutunu söyler; bir klasörse, o klasör de kendi içindekileri toplar. Siz ise "dosya mı klasör mü" diye ayrım yapmadan sadece "Boyutun ne?" diye sorarsınız.

Ordudan bir örnek

Bir general "İleri!" emri verir. Emir tümenlere, tümenlerden alaylara, oradan bölüklere ve en sonunda askerlere iner. General her askere tek tek seslenmez; emir hiyerarşi boyunca kendiliğinden yayılır.

Composite şunu der: "Bir parça ile parçalardan oluşan bir bütün aynı dili konuşsun; hangisiyle uğraştığını düşünmek zorunda kalma."
2

Teknik Anlamı

Bir yazılımcının bakış açısıyla

Composite, parça-bütün (part-whole) hiyerarşilerini temsil eder. Yaprak (leaf) ve kap (composite) nesneler ortak bir arayüzü uygular. Kap nesneler, işlemleri çocuklarına (children) özyinelemeli olarak delege eder.

Katılımcılar

Gerçek dünya kullanımları

Avantajlar

Dezavantajlar

3

C# ile Uygulama

Adım adım, çalışan kod örneği

Senaryo: Basit bir dosya sistemi. Toplam boyutu hesaplamak ve ağacı ekrana yazdırmak istiyoruz.

Adım 1 Component: ortak arayüz

public interface IFileSystemItem
{
    string Name { get; }
    long GetSize();
    void Print(string indent = "");
}

Adım 2 Leaf: dosya

public class FileItem : IFileSystemItem
{
    private readonly long _size;
    public string Name { get; }

    public FileItem(string name, long size) { Name = name; _size = size; }

    public long GetSize() => _size;

    public void Print(string indent = "") =>
        Console.WriteLine($"{indent}- {Name} ({_size} KB)");
}

Adım 3 Composite: klasör

Klasör hem IFileSystemItem'dır hem de IFileSystemItem listesi tutar. GetSize() çocuklarının boyutlarını toplar; çocuk klasörse o da kendi çocuklarını toplar.

public class Folder : IFileSystemItem
{
    private readonly List<IFileSystemItem> _children = new();
    public string Name { get; }

    public Folder(string name) => Name = name;

    public Folder Add(IFileSystemItem item) { _children.Add(item); return this; }

    public long GetSize() => _children.Sum(c => c.GetSize());

    public void Print(string indent = "")
    {
        Console.WriteLine($"{indent}+ {Name}/ ({GetSize()} KB)");
        foreach (var child in _children)
            child.Print(indent + "    ");
    }
}

Adım 4 Kullanım

Tüm parçaları bir araya getiren istemci (client) kodu:

var root = new Folder("Projelerim")
    .Add(new FileItem("notlar.txt", 4))
    .Add(new Folder("WebSitesi")
        .Add(new FileItem("index.html", 12))
        .Add(new FileItem("style.css", 8))
        .Add(new Folder("resimler")
            .Add(new FileItem("logo.png", 150))
            .Add(new FileItem("banner.jpg", 420))))
    .Add(new Folder("Bos klasor"));

root.Print();

// İstemci tek bir dosyayla da tüm ağaçla da aynı şekilde konuşur:
IFileSystemItem[] items = { new FileItem("tek.pdf", 300), root };
foreach (var item in items)
    Console.WriteLine($"{item.Name}: toplam {item.GetSize()} KB");

Konsol çıktısı

+ Projelerim/ (594 KB)
    - notlar.txt (4 KB)
    + WebSitesi/ (590 KB)
        - index.html (12 KB)
        - style.css (8 KB)
        + resimler/ (570 KB)
            - logo.png (150 KB)
            - banner.jpg (420 KB)
    + Bos klasor/ (0 KB)
tek.pdf: toplam 300 KB
Projelerim: toplam 594 KB

Kodda dikkat edilmesi gerekenler

Özetle: Composite, ağaç yapılarında tekil elemanlar ile gruplara aynı şekilde davranmayı sağlar; özyinelemeli işlemleri doğal ve sade hale getirir.
← Ana sayfaya dön