Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Leer Hierarchical Composition with Composite | Structural Patterns
C++ Design Patterns

bookHierarchical Composition with Composite

The Composite pattern is designed to let you compose objects into tree structures to represent part-whole hierarchies. This is especially useful when you want to treat individual objects and compositions of objects uniformly. Common scenarios include representing directories and files in a file system, graphical scene graphs, or organizational charts. By using the Composite pattern, you can build structures where both simple and complex elements conform to the same interface, allowing you to process them in a consistent way.

main.cpp

main.cpp

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
#include <iostream> #include <vector> #include <memory> #include <string> // Base Component class FileSystemEntity { public: virtual ~FileSystemEntity() = default; virtual void display(int indent = 0) const = 0; virtual size_t getSize() const = 0; }; // Leaf class File : public FileSystemEntity { std::string name_; size_t size_; public: File(const std::string& name, size_t size) : name_(name), size_(size) {} void display(int indent = 0) const override { std::cout << std::string(indent, ' ') << "- " << name_ << " (" << size_ << " bytes)" << std::endl; } size_t getSize() const override { return size_; } }; // Composite class Directory : public FileSystemEntity { std::string name_; std::vector<std::shared_ptr<FileSystemEntity>> children_; public: Directory(const std::string& name) : name_(name) {} void add(const std::shared_ptr<FileSystemEntity>& entity) { children_.push_back(entity); } void display(int indent = 0) const override { std::cout << std::string(indent, ' ') << "+ " << name_ << "/" << std::endl; for (const auto& child : children_) child->display(indent + 2); } size_t getSize() const override { size_t total = 0; for (const auto& child : children_) total += child->getSize(); return total; } }; int main() { auto root = std::make_shared<Directory>("root"); auto home = std::make_shared<Directory>("home"); auto user = std::make_shared<Directory>("user"); auto file1 = std::make_shared<File>("file1.txt", 1200); auto file2 = std::make_shared<File>("file2.txt", 800); auto file3 = std::make_shared<File>("notes.md", 500); user->add(file1); user->add(file2); home->add(user); root->add(home); root->add(file3); root->display(); std::cout << "Total size: " << root->getSize() << " bytes" << std::endl; }

Using the Composite pattern greatly simplifies client code that needs to work with tree-like structures. Instead of writing separate logic for handling files and directories, you interact with the base FileSystemEntity interface. Whether you traverse a single file or an entire directory tree, the same methods—such as display and getSize—can be called. This uniformity makes it easy to extend the hierarchy, add new types of components, or process the structure recursively without changing client code.

question mark

What is the main advantage of using the Composite pattern in hierarchical structures?

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 3. Hoofdstuk 3

Vraag AI

expand

Vraag AI

ChatGPT

Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.

Awesome!

Completion rate improved to 10

bookHierarchical Composition with Composite

Veeg om het menu te tonen

The Composite pattern is designed to let you compose objects into tree structures to represent part-whole hierarchies. This is especially useful when you want to treat individual objects and compositions of objects uniformly. Common scenarios include representing directories and files in a file system, graphical scene graphs, or organizational charts. By using the Composite pattern, you can build structures where both simple and complex elements conform to the same interface, allowing you to process them in a consistent way.

main.cpp

main.cpp

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
#include <iostream> #include <vector> #include <memory> #include <string> // Base Component class FileSystemEntity { public: virtual ~FileSystemEntity() = default; virtual void display(int indent = 0) const = 0; virtual size_t getSize() const = 0; }; // Leaf class File : public FileSystemEntity { std::string name_; size_t size_; public: File(const std::string& name, size_t size) : name_(name), size_(size) {} void display(int indent = 0) const override { std::cout << std::string(indent, ' ') << "- " << name_ << " (" << size_ << " bytes)" << std::endl; } size_t getSize() const override { return size_; } }; // Composite class Directory : public FileSystemEntity { std::string name_; std::vector<std::shared_ptr<FileSystemEntity>> children_; public: Directory(const std::string& name) : name_(name) {} void add(const std::shared_ptr<FileSystemEntity>& entity) { children_.push_back(entity); } void display(int indent = 0) const override { std::cout << std::string(indent, ' ') << "+ " << name_ << "/" << std::endl; for (const auto& child : children_) child->display(indent + 2); } size_t getSize() const override { size_t total = 0; for (const auto& child : children_) total += child->getSize(); return total; } }; int main() { auto root = std::make_shared<Directory>("root"); auto home = std::make_shared<Directory>("home"); auto user = std::make_shared<Directory>("user"); auto file1 = std::make_shared<File>("file1.txt", 1200); auto file2 = std::make_shared<File>("file2.txt", 800); auto file3 = std::make_shared<File>("notes.md", 500); user->add(file1); user->add(file2); home->add(user); root->add(home); root->add(file3); root->display(); std::cout << "Total size: " << root->getSize() << " bytes" << std::endl; }

Using the Composite pattern greatly simplifies client code that needs to work with tree-like structures. Instead of writing separate logic for handling files and directories, you interact with the base FileSystemEntity interface. Whether you traverse a single file or an entire directory tree, the same methods—such as display and getSize—can be called. This uniformity makes it easy to extend the hierarchy, add new types of components, or process the structure recursively without changing client code.

question mark

What is the main advantage of using the Composite pattern in hierarchical structures?

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 3. Hoofdstuk 3
some-alt