Decorator


Description:

Add responsibilities to objects dynamically

Intent

  • Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
  • Client-specified embellishment of a core object by recursively wrapping it.
  • Wrapping a gift, putting it in a box, and wrapping the box.

    Example:

    Note
    

Idea:

Check list

  1. Ensure the context is: a single core (or non-optional) component, several optional embellishments or wrappers, and an interface that is common to all.
  2. Create a "Lowest Common Denominator" interface that makes all classes interchangeable.
  3. Create a second level base class (Decorator) to support the optional wrapper classes.
  4. The Core class and Decorator class inherit from the LCD interface.
  5. The Decorator class declares a composition relationship to the LCD interface, and this data member is initialized in its constructor.
  6. The Decorator class delegates to the LCD object.
  7. Define a Decorator derived class for each optional embellishment.
  8. Decorator derived classes implement their wrapper functionality - and - delegate to the Decorator base class.
  9. The client configures the type and ordering of Core and Decorator objects.

Code:

class I {
  public:
    virtual ~I(){}
    virtual void do_it() = 0;
};

class A: public I {
  public:
    ~A() {
        cout << "A dtor" << '\n';
    }
    /*virtual*/
    void do_it() {
        cout << 'A';
    }
};

class D: public I {
  public:
    D(I *inner) {
        m_wrappee = inner;
    }
    ~D() {
        delete m_wrappee;
    }
    /*virtual*/
    void do_it() {
        m_wrappee->do_it();
    }
  private:
    I *m_wrappee;
};

class X: public D {
  public:
    X(I *core): D(core){}
    ~X() {
        cout << "X dtor" << "   ";
    }
    /*virtual*/
    void do_it() {
        D::do_it();
        cout << 'X';
    }
};

class Y: public D {
  public:
    Y(I *core): D(core){}
    ~Y() {
        cout << "Y dtor" << "   ";
    }
    /*virtual*/
    void do_it() {
        D::do_it();
        cout << 'Y';
    }
};

class Z: public D {
  public:
    Z(I *core): D(core){}
    ~Z() {
        cout << "Z dtor" << "   ";
    }
    /*virtual*/
    void do_it() {
        D::do_it();
        cout << 'Z';
    }
};

int main() { 
  I *anX = new X(new A);
  I *anXY = new Y(new X(new A));
  I *anXYZ = new Z(new Y(new X(new A)));
  anX->do_it();
  cout << '\n';
  anXY->do_it();
  cout << '\n';
  anXYZ->do_it();
  cout << '\n';
  delete anX;
  delete anXY;
  delete anXYZ;
}
Output

AX
AXY
AXYZ
X dtor   A dtor
Y dtor   X dtor   A dtor
Z dtor   Y dtor   X dtor   A dtor

results matching ""

    No results matching ""