Menu
Coddy logo textTech

Kompozit Kalıbı

Coddy'nin C# Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 61 / 70.

Composite deseni, nesneleri ağaç yapıları hâlinde birleştirmenize ve tek tek nesnelerle nesne gruplarını aynı şekilde ele almanıza olanak tanıyan yapısal bir desendir. Aynı arayüz üzerinden hem tekil öğelerle hem de koleksiyonlarla çalışmak istediğiniz parça-bütün hiyerarşilerini temsil etmek için idealdir.

Desen üç ana bileşene sahiptir: ortak işlemleri tanımlayan bir bileşen arayüzü, tekil nesneleri temsil eden yaprak sınıflar ve alt öğeleri içeren ve aynı arayüzü uygulayan bileşik sınıflar:

public interface IFileSystemItem
{
    string Name { get; }
    int GetSize();
}

public class File : IFileSystemItem
{
    public string Name { get; }
    private int _size;
    
    public File(string name, int size)
    {
        Name = name;
        _size = size;
    }
    
    public int GetSize() => _size;
}

public class Folder : IFileSystemItem
{
    public string Name { get; }
    private List<IFileSystemItem> _items = new List<IFileSystemItem>();
    
    public Folder(string name) => Name = name;
    
    public void Add(IFileSystemItem item) => _items.Add(item);
    
    public int GetSize() => _items.Sum(item => item.GetSize());
}

Bu desenin güzelliği, istemcilerin tek bir dosyayla mı yoksa tüm bir klasör hiyerarşisiyle mi çalıştıklarını bilmelerine gerek olmamasıdır:

var root = new Folder("root");
root.Add(new File("doc.txt", 100));

var subFolder = new Folder("images");
subFolder.Add(new File("photo.jpg", 500));
subFolder.Add(new File("icon.png", 50));

root.Add(subFolder);

Console.WriteLine(root.GetSize());  // 650

Composite deseni; dosya sistemleri, UI bileşen ağaçları, organizasyon şemaları veya kapsayıcıların ve içeriklerin aynı şekilde ele alınması gereken her yapı için idealdir. Basit ve karmaşık öğeler arasında ayrım yapma gereksinimini ortadan kaldırarak istemci kodunu basitleştirir.

challenge icon

Görev

Kolay

Composite desenini kullanarak bir organizasyon şeması sistemi oluşturalım. Hem bireysel çalışanların hem de çalışanlar veya diğer departmanları içeren departmanların aynı şekilde ele alınabildiği bir yapı oluşturacaksın. Böylece hiyerarşinin herhangi bir düzeyindeki toplam maaş maliyetini hesaplayabileceksin.

Kodunu üç dosyaya ayıracaksın:

  • OrgComponent.cs: IOrgComponent namespace'i içinde bir Organization arayüzü tanımla. Bu arayüzde iki üye bulunmalı: bir Name özelliği (string) ve bir tamsayı döndüren GetSalary() metodu. Bu arayüz, hem bireysel çalışanların hem de departmanların uyacağı ortak sözleşmeyi temsil eder.
  • OrgClasses.cs: Aynı namespace içinde iki sınıf oluştur:
    • Employee - bireysel bir çalışanı temsil eden yaprak sınıf. Yapıcısında bir ad ve maaş alır ve kendi maaşını döndürerek arayüzü uygular.
    • Department - bir grubu temsil eden bileşik sınıf. Yapıcısında bir ad alır ve IOrgComponent öğelerinden oluşan bir liste tutar. Üye eklemek için bir Add(IOrgComponent component) metodu ekle. GetSalary() metodu, tüm üyelerinin maaşlarının toplamını döndürmelidir.
  • Program.cs: Girdiye dayalı bir organizasyon yapısı oluştur ve toplam maaşı hesapla. Departmanlar ve çalışanlar oluşturacak, bunları uygun şekilde iç içe yerleştirecek ve Composite deseninin tüm hiyerarşiyi aynı şekilde ele almanı nasıl sağladığını göstereceksin.

Aşağıdaki girdileri alacaksın:

  • Oluşturulacak bileşenlerin sayısı
  • Her bileşen için tür (employee veya department), ardından ad ve çalışanlar için maaş. Departmanlar için ayrıca üst departmanın adını da alacaksın (veya üst düzey bir departmansa root)

Her bileşen için giriş biçimi:

employee
{name}
{salary}
{parent_department}

department
{name}
{parent_department}

Yapıyı oluşturduktan sonra kök departmanın toplam maaşını {root_name} Total Salary: {amount} biçiminde yazdır.

Örneğin girdiler şöyleyse:

5
department
Engineering
root
employee
Alice
5000
Engineering
employee
Bob
4500
Engineering
department
QA
Engineering
employee
Charlie
4000
QA

Çıktı şöyle olmalıdır:

Engineering Total Salary: 13500

Engineering departmanı Alice (5000), Bob (4500) ve QA departmanını içerir. QA, Charlie'yi (4000) içerir. Engineering üzerinde GetSalary() metodunu çağırdığında, tüm iç içe bileşenlerin toplamını özyinelemeli olarak hesaplar. Bu da Composite deseninin karmaşık ağaç yapılarını basit ve tek tip bir arayüz üzerinden ele almanı nasıl sağladığını gösterir!

Kendin dene

using System;
using System.Collections.Generic;
using Organization;

class Program
{
    public static void Main(string[] args)
    {
        int n = Convert.ToInt32(Console.ReadLine());
        
        // TODO: Departmanları isme göre saklamak için bir sözlük (dictionary) oluşturun
        // Bu, bileşenleri eklerken üst departmanları bulmanıza yardımcı olacaktır
        Dictionary<string, Department> departments = new Dictionary<string, Department>();
        
        // TODO: Kök (root) departmanı takip edin
        Department root = null;
        
        for (int i = 0; i < n; i++)
        {
            string type = Console.ReadLine();
            
            if (type == "department")
            {
                string name = Console.ReadLine();
                string parent = Console.ReadLine();
                
                // TODO: Departmanı oluşturun
                // TODO: Onu departments sözlüğüne ekleyin
                // TODO: Eğer parent "root" ise, bu kök departmandır
                // TODO: Aksi takdirde, üst departmanı bulun ve bu departmanı ona ekleyin
            }
            else if (type == "employee")
            {
                string name = Console.ReadLine();
                int salary = Convert.ToInt32(Console.ReadLine());
                string parent = Console.ReadLine();
                
                // TODO: Çalışanı oluşturun
                // TODO: Üst departmanı bulun ve çalışanı ona ekleyin
            }
        }
        
        // TODO: Kök departmanın toplam maaşını yazdırın
        // Format: "{root_name} Total Salary: {amount}"
        Console.WriteLine($"{root.Name} Total Salary: {root.GetSalary()}");
    }
}
quiz iconKendini test et

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

Kendi başına pratik yap: Online C# derleyicisi