Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Implementing the Decorator Pattern in C++ for Dynamic Function Extension

Tech May 13 2

The Decorator pattern enables adding new responsibilities to an object dynamically without altering its structure. It creates a chain of decorators, each wrapping the previous object, forming a linked structure similar to a linked list. This approach maintains references to original functionality while introducing new behavior.

Consider a scenario where a person's outfit is assembled dynamically. Each clothing item decorates the person's base state, adding its own description while preserving the previous layers.

1. Base Component Interface

class OutfitComponent {
public:
    virtual ~OutfitComponent() {}
    virtual void display() const {
        std::cout << "Basic outfit.\n";
    }
};

2. Abstract Decorator Class

class ClothingDecorator : public OutfitComponent {
public:
    ClothingDecorator() : wrappedComponent(nullptr) {}
    virtual ~ClothingDecorator() {}

    void display() const override {
        if (wrappedComponent) {
            wrappedComponent->display();
        }
    }

    void wrap(OutfitComponent* component) {
        wrappedComponent = component;
    }

private:
    OutfitComponent* wrappedComponent;
};

3. Concrete Decorator Implementations

class TShirtDecorator : public ClothingDecorator {
public:
    void display() const override {
        std::cout << "T-shirt ";
        ClothingDecorator::display();
    }
};

class JeansDecorator : public ClothingDecorator {
public:
    void display() const override {
        std::cout << "Jeans ";
        ClothingDecorator::display();
    }
};

Each concrete decorator outputs its own description before delegating to the wrapped component's display method, preserving the chain of functionality.

4. Assembling the Decorated Object

int main() {
    OutfitComponent person;
    TShirtDecorator shirt;
    JeansDecorator jeans;

    shirt.wrap(&person);
    jeans.wrap(&shirt);
    jeans.display();

    return 0;
}

Execution flows from the outermost decorator inward: JeansDecorator::display() prints "Jeans", then calls TShirtDecorator::display() which prints "T-shirt", finally invoking the base OutfitComponent::display() that outputs "Basic outfit.".

5. Pattern Flexibiilty and Applications The Decorator pattern supports runtime modification of object behavior. To change the outfit, simply create a new decorator and adjust the wrapping order. For instance, adding a JacketDecorator:

class JacketDecorator : public ClothingDecorator {
public:
    void display() const override {
        std::cout << "Jacket ";
        ClothingDecorator::display();
    }
};

This pattern is particularly effective for etxending functionality in layered systems. Consider a text processing system with a base text editor. Decorators can add features like syntax highlighting, spell checking, or auto-formatting. Each decorator performs its specific operation before or after delegating to the wrapped component, allowing flexible combination of features without modifying core classes.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.