Kompozit Kalıbı
Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 101 / 104.
Composite deseni, tek tek nesnelere ve nesne gruplarına aynı şekilde davranmanızı sağlar. Nesneleri, hem tek öğelerin hem de öğe kapsayıcılarının aynı arayüzü paylaştığı ağaç yapıları hâlinde birleştirir. Bu, dosya sistemleri, organizasyon şemaları veya kullanıcı arayüzü bileşenleri gibi hiyerarşileri temsil etmek için idealdir.
Örüntünün üç temel bölümü vardır: ortak işlemleri tanımlayan bir Component arayüzü, tek tek nesneleri temsil eden Leaf sınıfları ve alt öğeleri içeren ve işlemleri onlara devreden Composite sınıfları:
#include <iostream>
#include <memory>
#include <vector>
#include <string>
// Bileşen arayüzü
class FileSystemItem {
public:
virtual void display(int indent = 0) const = 0;
virtual int getSize() const = 0;
virtual ~FileSystemItem() = default;
};
// Yaprak - bireysel dosyaları temsil eder
class File : public FileSystemItem {
std::string name;
int size;
public:
File(const std::string& n, int s) : name(n), size(s) {}
void display(int indent = 0) const override {
std::cout << std::string(indent, ' ') << name
<< " (" << size << " KB)\n";
}
int getSize() const override { return size; }
};
// Bileşik - diğer bileşenleri içerir
class Folder : public FileSystemItem {
std::string name;
std::vector<std::shared_ptr<FileSystemItem>> children;
public:
Folder(const std::string& n) : name(n) {}
void add(std::shared_ptr<FileSystemItem> item) {
children.push_back(item);
}
void display(int indent = 0) const override {
std::cout << std::string(indent, ' ') << "[" << name << "]\n";
for (const auto& child : children) {
child->display(indent + 2);
}
}
int getSize() const override {
int total = 0;
for (const auto& child : children) {
total += child->getSize();
}
return total;
}
};Folder bileşiği, alt öğeleri depolar ve bunlar üzerinde yineleme yaparak işlemleri gerçekleştirir. Bir klasör üzerinde getSize() çağırdığınızda, içerdiği tüm öğelerin toplam boyutunu özyinelemeli olarak hesaplar. İstemci kodunun bir dosyayla mı yoksa bir klasörle mi çalıştığını bilmesine gerek yoktur; her ikisi de aynı arayüze yanıt verir.
Parça-bütün hiyerarşilerini temsil etmeniz gerektiğinde ve istemcilerin tek tek nesnelerle bileşimleri aynı şekilde işlemesini istediğinizde Composite kullanın.
Görev
KolayComposite desenini kullanarak bir Organizasyon Şeması sistemi oluşturalım. Hem bireysel çalışanların hem de diğer çalışanları veya alt departmanları içeren departmanların aynı şekilde ele alınabileceği bir hiyerarşi oluşturacaksınız. Bu, gerçek şirketlerin nasıl yapılandırıldığını yansıtır: departmanlar insanları ve diğer departmanları içererek bir ağaç yapısı oluşturur.
Kodunuzu üç dosyaya düzenleyeceksiniz:
OrgComponent.h: Hem çalışanların hem de departmanların uygulayacağı bileşen arayüzünü tanımlayın.Aşağıdakilere sahip soyut bir
OrgComponentsınıfı oluşturun:getName(): bileşenin adını döndürürgetSalary(): toplam maaşı döndürür (çalışanlar için kendi maaşları; departmanlar için içerilen tüm maaşların toplamı)display(int indent = 0): bileşeni uygun girintilemeyle görüntüler
Sanal bir yıkıcı ekleyin.
Organization.h: yaprak ve bileşik sınıfları uygulayın.Bir ad ve maaş saklayan bir
Employeesınıfı (yaprak) oluşturun.display()metodu, çalışanın bilgilerini şu biçimde yazdırmalıdır:[indent spaces]- [name] ($[salary])Departmentkullanarak bir ad veOrgComponentalt öğelerinden oluşan bir koleksiyon saklayan birstd::shared_ptrsınıfı (bileşik) oluşturun. Şunları uygulayın:add(std::shared_ptr<OrgComponent> component): departmana bir alt öğe eklergetSalary(): tüm üyelerin toplam maaşını özyinelemeli olarak hesaplardisplay(): departman adını köşeli parantezler içinde yazdırır, ardından tüm alt öğeleri artırılmış girintiyle görüntüler (seviye başına 2 boşluk ekleyin)
Departmanın görüntüleme biçimi şu şekilde olmalıdır:
[indent spaces][Department Name] [children displayed with indent + 2]main.cpp: bir organizasyon yapısı oluşturun ve görüntüleyin.Dört girdi okuyun:
- Şirket adı (string)
- Departman adı (string)
- İlk çalışanın adı ve maaşı (biçim:
name,salary) - İkinci çalışanın adı ve maaşı (biçim:
name,salary)
Bu yapıyı oluşturun: Bir şirket (en üst düzey departman) oluşturun, buna bir alt departman ekleyin ve her iki çalışanı da bu alt departmana ekleyin. Ardından tüm organizasyonu görüntüleyin ve toplam şirket maaşını yazdırın.
Yapıyı görüntüledikten sonra şunu yazdırın:
Total Salary: $[amount]
Örneğin TechCorp, Engineering, Alice,75000 ve Bob,65000 girdileriyle:
[TechCorp]
[Engineering]
- Alice ($75000)
- Bob ($65000)
Total Salary: $140000StartupInc, Development, Carol,80000 ve Dave,70000 girdileriyle:
[StartupInc]
[Development]
- Carol ($80000)
- Dave ($70000)
Total Salary: $150000getSalary() metodunun bir çalışan veya departman üzerinde çağrılmasına bakılmaksızın nasıl aynı şekilde çalıştığına dikkat edin: departman, tüm üyelerinin maaşlarını otomatik olarak toplar. Toplamları hesaplarken veya hiyerarşiyi görüntülerken istemci kodunun bireysel çalışanlar ile tüm departmanlar arasında ayrım yapmasına gerek yoktur.
Kendin dene
#include <iostream>
#include <string>
#include <memory>
#include <sstream>
#include "Organization.h"
int main() {
// Girdileri oku
std::string companyName;
std::string departmentName;
std::string employee1Input;
std::string employee2Input;
std::getline(std::cin, companyName);
std::getline(std::cin, departmentName);
std::getline(std::cin, employee1Input);
std::getline(std::cin, employee2Input);
// "name,salary" formatını ayrıştırmak için yardımcı lambda
auto parseEmployee = [](const std::string& input) -> std::pair<std::string, int> {
size_t commaPos = input.find(',');
std::string name = input.substr(0, commaPos);
int salary = std::stoi(input.substr(commaPos + 1));
return {name, salary};
};
auto [name1, salary1] = parseEmployee(employee1Input);
auto [name2, salary2] = parseEmployee(employee2Input);
// TODO: Şirketi üst düzey bir Department olarak oluştur
// TODO: Bir alt departman oluştur
// TODO: Ayrıştırılmış verileri kullanarak iki Employee nesnesi oluştur
// TODO: Çalışanları alt departmana ekle
// TODO: Alt departmanı şirkete ekle
// TODO: Tüm organizasyon yapısını görüntüle
// TODO: Toplam maaşı şu formatta yazdır: Total Salary: $[amount]
return 0;
}
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 DosyalarC++ Build ve DerlemeBaşlık Dosyaları ve Kaynak DosyalarıAd Alanları ve KapsamC++'ta OOP'ye GirişSınıflar ve Nesneler'this' İşaretçisiMetotlar (Üye Fonksiyonlar)Öznitelikler (Veri Üyeleri)Ctor ve Dtor TemelleriÖzet - Basit Hesap Makinesi4Sınıf Özellikleri
Örnek ve Statik ÜyelerGetter ve Setter MetotlarıConst Üye FonksiyonlarMutable Anahtar KelimesiStatik Metotlar ve DeğişkenlerFriend Fonksiyonlar ve SınıflarÖzet - Banka Hesabı Yöneticisi7Kalıtım
Temel KalıtımKalıtım Erişim SeviyeleriCtor ve Dtor Çağrılma SırasıMetot Geçersiz KılmaSanal Fonksiyonlar ve VTableÇoklu KalıtımSanal KalıtımÖzet - Çalışan Hiyerarşisi10STL Genel Bakış
STL Genel Bakış ve FelsefesiSTL KonteynerleriİteratörlerSTL AlgoritmalarıFunctor'lar ve Lambda İfadeleriÖzet - Kelime Frekansı13Tasarım Kalıpları 1. Bölüm
Tasarım Kalıplarına GirişSingleton KalıbıFactory ve Abstract FactoryBuilder KalıbıObserver KalıbıStrategy Kalıbı2Bellek Yönetimi
Stack ve Heap Bellekİşaretçiler ve ReferanslarDinamik Bellek (new/delete)C++'ta Akıllı İşaretçilerC++'ta RAIIÖzet - Dinamik Dizi Yöneticisi5Kapsülleme
C++'da Erişim BelirleyicilerDerinlemesine Erişim BelirleyicilerBilgi GizlemeStruct vs Classİç İçe ve Dahili SınıflarÖzet - Öğrenci Kayıt Sistemi8Çok Biçimlilik
Derleme ve Çalışma Zamanı Çok BiçimliliğiFonksiyon Aşırı YüklemeSanal Fonksiyonlara Yeniden BakışSaf Sanal FonksiyonlarSoyut SınıflarC++'ta Arayüz TasarımıDynamic Casting ve RTTIÖzet - Şekil Hesaplayıcı11İleri Düzey OOP Kavramları
Kompozisyon ve Kalıtım KarşılaştırmasıCRTP ile Mixin YapılarıPimpl İdiyomuTür Silme (Type Erasure)Enum Sınıfları ve Güçlü TiplendirmeOOP'de İstisna YönetimiÖzel İstisna Hiyerarşileri14Tasarı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ıBir Kalıp Olarak RAII3Yapıcılar ve Yıkıcılar
Varsayılan YapıcıParametreli YapıcıKopya YapıcıTaşıma YapıcısıYapıcı İlklendirme ListeleriTemsilci YapıcılarYıkıcılara Derinlemesine BakışÜç / Beş / Sıfır KuralıÖzet - String Sınıfı6Operatör Aşırı Yükleme
Operatör Aşırı Yüklemeye GirişAritmetik Operatör Aşırı YüklemeKarşılaştırma Operatörü Aşırı YüklemeStream OperatörleriAtama Operatörü Aşırı Yükleme[] ve () Operatör Aşırı YüklemeTip Dönüşüm OperatörleriÖzet - Matris Sınıfı9Şablonlar
Fonksiyon ŞablonlarıSınıf ŞablonlarıŞablon ÖzelleştirmeVariadic ŞablonlarSFINAE ve Type Traits TemelleriÖzet - Generic KonteynerKendi başına pratik yap: Online C++ derleyicisi