Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Вивчайте Dynamic Functionality Extension with Decorator | Structural Patterns
C++ Design Patterns

bookDynamic Functionality Extension with Decorator

The Decorator pattern enables you to add new responsibilities to objects dynamically, without modifying their code or relying on deep inheritance hierarchies. This approach is especially useful when you want to extend the behavior of individual objects, rather than all instances of a class. By wrapping an object with one or more decorators, you can compose new functionality at runtime. Unlike subclassing, which can lead to a rigid and complex class structure, Decorator allows you to mix and match features flexibly and transparently.

main.cpp

main.cpp

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
#include <iostream> #include <string> #include <memory> // The base Writer interface class Writer { public: virtual ~Writer() = default; virtual void write(const std::string& data) = 0; }; // Concrete Writer implementation class FileWriter : public Writer { public: void write(const std::string& data) override { std::cout << "[FileWriter] Writing: " << data << std::endl; } }; // Decorator base class class WriterDecorator : public Writer { protected: std::unique_ptr<Writer> wrappee; public: WriterDecorator(std::unique_ptr<Writer> w) : wrappee(std::move(w)) {} }; // Logging Decorator class LoggingWriter : public WriterDecorator { public: LoggingWriter(std::unique_ptr<Writer> w) : WriterDecorator(std::move(w)) {} void write(const std::string& data) override { std::cout << "[LoggingWriter] Logging data: " << data << std::endl; wrappee->write(data); } }; // Encryption Decorator class EncryptingWriter : public WriterDecorator { public: EncryptingWriter(std::unique_ptr<Writer> w) : WriterDecorator(std::move(w)) {} void write(const std::string& data) override { std::string encrypted = encrypt(data); std::cout << "[EncryptingWriter] Encrypting data: " << encrypted << std::endl; wrappee->write(encrypted); } private: std::string encrypt(const std::string& input) { std::string result = input; for (auto& c : result) c += 1; // Simple Caesar cipher: shift chars by 1 return result; } }; int main() { std::unique_ptr<Writer> writer = std::make_unique<FileWriter>(); writer = std::make_unique<LoggingWriter>(std::move(writer)); writer = std::make_unique<EncryptingWriter>(std::move(writer)); writer->write("Hello, Decorator!"); }

The Decorator pattern supports the open/closed principle by allowing you to extend an object's behavior without altering its source code. This makes your system open for extension but closed for modification. You can stack multiple decorators to combine features such as logging, encryption, buffering, or compression in any order, giving you highly flexible and reusable components. This compositional approach also helps avoid the exponential growth of subclasses that would be required to support every possible combination of features through inheritance.

question mark

What is a primary benefit of using the Decorator pattern in C++?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 3. Розділ 2

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

Awesome!

Completion rate improved to 10

bookDynamic Functionality Extension with Decorator

Свайпніть щоб показати меню

The Decorator pattern enables you to add new responsibilities to objects dynamically, without modifying their code or relying on deep inheritance hierarchies. This approach is especially useful when you want to extend the behavior of individual objects, rather than all instances of a class. By wrapping an object with one or more decorators, you can compose new functionality at runtime. Unlike subclassing, which can lead to a rigid and complex class structure, Decorator allows you to mix and match features flexibly and transparently.

main.cpp

main.cpp

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
#include <iostream> #include <string> #include <memory> // The base Writer interface class Writer { public: virtual ~Writer() = default; virtual void write(const std::string& data) = 0; }; // Concrete Writer implementation class FileWriter : public Writer { public: void write(const std::string& data) override { std::cout << "[FileWriter] Writing: " << data << std::endl; } }; // Decorator base class class WriterDecorator : public Writer { protected: std::unique_ptr<Writer> wrappee; public: WriterDecorator(std::unique_ptr<Writer> w) : wrappee(std::move(w)) {} }; // Logging Decorator class LoggingWriter : public WriterDecorator { public: LoggingWriter(std::unique_ptr<Writer> w) : WriterDecorator(std::move(w)) {} void write(const std::string& data) override { std::cout << "[LoggingWriter] Logging data: " << data << std::endl; wrappee->write(data); } }; // Encryption Decorator class EncryptingWriter : public WriterDecorator { public: EncryptingWriter(std::unique_ptr<Writer> w) : WriterDecorator(std::move(w)) {} void write(const std::string& data) override { std::string encrypted = encrypt(data); std::cout << "[EncryptingWriter] Encrypting data: " << encrypted << std::endl; wrappee->write(encrypted); } private: std::string encrypt(const std::string& input) { std::string result = input; for (auto& c : result) c += 1; // Simple Caesar cipher: shift chars by 1 return result; } }; int main() { std::unique_ptr<Writer> writer = std::make_unique<FileWriter>(); writer = std::make_unique<LoggingWriter>(std::move(writer)); writer = std::make_unique<EncryptingWriter>(std::move(writer)); writer->write("Hello, Decorator!"); }

The Decorator pattern supports the open/closed principle by allowing you to extend an object's behavior without altering its source code. This makes your system open for extension but closed for modification. You can stack multiple decorators to combine features such as logging, encryption, buffering, or compression in any order, giving you highly flexible and reusable components. This compositional approach also helps avoid the exponential growth of subclasses that would be required to support every possible combination of features through inheritance.

question mark

What is a primary benefit of using the Decorator pattern in C++?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 3. Розділ 2
some-alt