Pola Composite
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 101 dari 104.
Pola Composite memungkinkan kamu memperlakukan object individual dan kelompok object secara seragam. Pola ini menyusun object menjadi struktur pohon, tempat elemen tunggal dan container elemen menggunakan antarmuka yang sama. Pola ini ideal untuk merepresentasikan hierarki seperti sistem file, bagan organisasi, atau komponen UI.
Pola ini memiliki tiga bagian utama: antarmuka Component yang mendefinisikan operasi umum, class Leaf yang merepresentasikan object individual, dan class Composite yang berisi anak dan mendelegasikan operasi kepada mereka:
#include <iostream>
#include <memory>
#include <vector>
#include <string>
// Antarmuka komponen
class FileSystemItem {
public:
virtual void display(int indent = 0) const = 0;
virtual int getSize() const = 0;
virtual ~FileSystemItem() = default;
};
// Daun: mewakili file individual
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; }
};
// Komposit: berisi komponen lain
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;
}
};Composite Folder menyimpan child dan mengimplementasikan operasi dengan melakukan iterasi pada child tersebut. Saat kamu memanggil getSize() pada folder, composite tersebut menghitung total ukuran semua item di dalamnya secara rekursif. Kode client tidak perlu mengetahui apakah kode tersebut bekerja dengan file atau folder, keduanya merespons dengan interface yang sama.
Gunakan Composite saat kamu perlu merepresentasikan hierarki bagian-keseluruhan dan ingin client memperlakukan object individual dan komposisi secara seragam.
Tantangan
MudahMari kita buat sistem Bagan Organisasi menggunakan pola Composite. Kamu akan membuat hierarki tempat karyawan perorangan dan departemen, yang berisi karyawan lain atau subdepartemen, dapat diperlakukan secara seragam. Ini mencerminkan struktur perusahaan di dunia nyata: departemen berisi orang dan departemen lain, sehingga membentuk struktur pohon.
Kamu akan mengatur kodemu dalam tiga file:
OrgComponent.h: Definisikan antarmuka komponen yang akan diterapkan oleh karyawan dan departemen.Buat class abstrak
OrgComponentdengan:getName(): mengembalikan nama komponengetSalary(): mengembalikan total gaji. Untuk karyawan, gaji mereka sendiri. Untuk departemen, jumlah semua gaji yang tercakup di dalamnya.display(int indent = 0): menampilkan komponen dengan indentasi yang sesuai
Sertakan destructor virtual.
Organization.h: Implementasikan class leaf dan composite.Buat class
Employee(leaf) yang menyimpan nama dan gaji. Methoddisplay()-nya harus mencetak informasi karyawan dengan format berikut:[indent spaces]- [name] ($[salary])Buat class
Department(composite) yang menyimpan nama dan kumpulan anakOrgComponentmenggunakanstd::shared_ptr. Implementasikan:add(std::shared_ptr<OrgComponent> component): menambahkan anak ke departemengetSalary(): menghitung total gaji semua anggota secara rekursifdisplay(): mencetak nama departemen di dalam tanda kurung siku, lalu menampilkan semua anak dengan indentasi yang bertambah sebanyak 2 spasi per tingkat
Format tampilan departemen harus seperti berikut:
[indent spaces][Department Name] [children displayed with indent + 2]main.cpp: Buat dan tampilkan struktur organisasi.Baca empat input:
- Nama perusahaan (string)
- Nama departemen (string)
- Nama dan gaji karyawan pertama (format:
name,salary) - Nama dan gaji karyawan kedua (format:
name,salary)
Buat struktur ini: Buat perusahaan (departemen tingkat teratas), tambahkan subdepartemen ke dalamnya, lalu tambahkan kedua karyawan ke subdepartemen tersebut. Setelah itu, tampilkan seluruh organisasi dan cetak total gaji perusahaan.
Setelah menampilkan struktur, cetak:
Total Salary: $[amount]
Contohnya, dengan input TechCorp, Engineering, Alice,75000, dan Bob,65000:
[TechCorp]
[Engineering]
- Alice ($75000)
- Bob ($65000)
Total Salary: $140000Dengan input StartupInc, Development, Carol,80000, dan Dave,70000:
[StartupInc]
[Development]
- Carol ($80000)
- Dave ($70000)
Total Salary: $150000Perhatikan bahwa getSalary() bekerja secara seragam, baik dipanggil pada karyawan maupun departemen: departemen secara otomatis mengakumulasi gaji semua anggotanya. Kode client tidak perlu membedakan karyawan perorangan dan seluruh departemen saat menghitung total atau menampilkan hierarki.
Coba sendiri
#include <iostream>
#include <string>
#include <memory>
#include <sstream>
#include "Organization.h"
int main() {
// Baca input
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);
// Lambda pembantu untuk mengurai format "name,salary"
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: Buat perusahaan sebagai Department tingkat teratas
// TODO: Buat subdepartemen
// TODO: Buat dua object Employee menggunakan data yang telah diurai
// TODO: Tambahkan kedua karyawan ke subdepartemen
// TODO: Tambahkan subdepartemen ke perusahaan
// TODO: Tampilkan seluruh struktur organisasi
// TODO: Cetak total gaji dengan format: Total Salary: $[amount]
return 0;
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Dasar-Dasar OOP
File EksternalBuild dan Kompilasi C++File Header dan File SourceNamespace dan CakupanPengantar OOP dalam C++class vs objectPointer 'this'method (Fungsi Anggota)Atribut (Anggota Data)Dasar Ctor dan DtorRingkasan: Kalkulator Sederhana4Properti class
Anggota instance vs staticGetter dan setterFungsi anggota constKata kunci mutableMethod dan variabel staticFungsi dan class friendRangkuman, Pengelola Rekening Bank7Pewarisan
Pewarisan DasarTingkat Akses pada PewarisanUrutan Pemanggilan Ctor & DtorPenimpaan methodFungsi Virtual & VTablePewarisan BergandaPewarisan VirtualRangkuman: Hierarki Karyawan2Manajemen Memori
Memori Stack vs HeapPointer dan ReferenceMemori Dinamis (new/delete)Smart Pointer di C++RAII di C++Rangkuman: Pengelola Array Dinamis5Enkapsulasi
Penentu Akses dalam C++Penentu Akses secara MendalamPenyembunyian Informasistruct vs classNested dan Inner classRangkuman, Sistem Catatan Siswa8Polimorfisme
Polimorfisme saat Compile vs RuntimeOverloading FungsiMeninjau Kembali Fungsi VirtualFungsi Virtual MurniKelas AbstrakDesain Interface di C++Casting Dinamis & RTTIRangkuman: Kalkulator Bentuk11Konsep OOP Lanjutan
Komposisi vs PewarisanMixin melalui CRTPIdiom PimplPenghapusan TipeKelas Enum dan Pengetikan KuatPenanganan Pengecualian dalam OOPHierarki Pengecualian Kustom14Pola Desain Bagian 2
Pola CommandPola AdapterPola DecoratorPola Template MethodPola StatePola CompositeRAII sebagai Pola3Konstruktor & Destruktor
Konstruktor DefaultKonstruktor BerparameterKonstruktor SalinKonstruktor PindahDaftar Inisialisasi KonstruktorKonstruktor DelegasiKupas Tuntas DestruktorAturan Tiga, Lima, dan NolRangkuman: class String6Overloading Operator
Pengantar Overloading OperatorOverloading Operator AritmetikaOverloading Operator PerbandinganOperator StreamOverloading Operator PenugasanOverloading Operator [] dan ()Operator Konversi TipeRingkasan, class Matrix9Template
Template FungsiTemplate classSpesialisasi TemplateTemplate VariadikDasar SFINAE & Type TraitsRangkuman, Container GenerikLatihan sendiri: Compiler C++ online