Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære 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

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 3. Kapitel 3

Spørg AI

expand

Spørg AI

ChatGPT

Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat

Suggested prompts:

Can you give an example of how the Composite pattern is implemented in code?

What are some real-world use cases for the Composite pattern?

How does the Composite pattern differ from other structural patterns?

Awesome!

Completion rate improved to 10

bookHierarchical Composition with Composite

Stryg for at vise menuen

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

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 3. Kapitel 3
some-alt