Design Patterns Explained C++ Code Examples – Chapter 17: The Decorator Pattern


Example 17-1: Decorator

TOC

Client

TOP
Client.h

#pragma once
#include "Factory.h"
#include "Component.h"

class Client
{
public:
    Client(void);
public:
    ~Client(void);
};

Client.cpp

#include "Client.h"

Client::Client(void)
{
}

Client::~Client(void)
{
}

static void main ()
{
    Factory myFactory;
    Component *myComponent = myFactory.getComponent();
}

Factory

TOP
Factory.h

#pragma once
#include "Component.h"
#include "SalesTicket.h"
#include "Header1.h"
#include "Header2.h"
#include "Footer1.h"
#include "Footer2.h"

class Factory
{
public:
    Factory(void);
    Component* getComponent();
public:
    ~Factory(void);
};

Factory.cpp

#include "Factory.h"

Factory::Factory(void)
{
}

Factory::~Factory(void)
{
}

Component *Factory::getComponent()
{
    bool doHeader1;
    bool doHeader2;
    bool doFooter1;
    bool doFooter2;

    // Put code here that sets doHeader1, doHeader2, doFooter1, doFooter2
    // One way could look up in a configuration file.
    // Here I'll hardcode an example that gives a footer1 and a header1
    doHeader1= true;
    doHeader2= false;
    doFooter1= true;
    doFooter2= false;

    Component *myComponent;
    myComponent = new SalesTicket;

    // Note that the chain is built backwards so the last one instantiated
    // is at the front of the list
    if (doFooter2) myComponent= new Footer2( myComponent);
    if (doFooter1) myComponent= new Footer1( myComponent);
    if (doHeader2) myComponent= new Header2( myComponent);
    if (doHeader1) myComponent= new Header1( myComponent);

    return (myComponent);
}

Component

TOP
Component.h

#pragma once

class Component
{
public:
    Component(void);
    virtual void prtTicket()= 0;
public:
    ~Component(void);
};

Component.cpp

#include "Component.h"

Component::Component(void)
{
}

Component::~Component(void)
{
}

SalesTicket

TOP
SalesTicket.h

#pragma once
#include "component.h"

class SalesTicket :    public Component
{
public:
    SalesTicket(void);
    void prtTicket();
public:
    ~SalesTicket(void);
};

SalesTicket.cpp

#include "SalesTicket.h"

SalesTicket::SalesTicket(void)
{
}

SalesTicket::~SalesTicket(void)
{
}

void SalesTicket::prtTicket(void)
{
    // place sales ticket printing code here
}

TicketDecorator

TOP
TicketDecorator.h

#pragma once
#include "component.h"

class TicketDecorator :    public Component
{
public:
    TicketDecorator(Component *myComponent);
    void callTrailer();
public:
    ~TicketDecorator(void);
private:
     Component *myTrailer;
};

TicketDecorator.cpp

#include "TicketDecorator.h"

TicketDecorator::TicketDecorator(Component *myComponent)
{
    myTrailer= myComponent;
}

TicketDecorator::~TicketDecorator(void)
{
}

void TicketDecorator::callTrailer()
{
    if (myTrailer != 0l) myTrailer->prtTicket();
}

Header1

TOP
Header1.h

#pragma once
#include "ticketdecorator.h"

class Header1 :    public TicketDecorator
{
public:
    Header1(Component *myComponent); 
    void prtTicket();
public:
    ~Header1(void);
};

Header1.cpp

#include "Header1.h"

Header1::Header1(Component *myComponent) : TicketDecorator( myComponent)
{
}

Header1::~Header1(void)
{
}

void Header1::prtTicket()
{
    // place printing header 1 code here
    callTrailer();
}

Header2

TOP
Header2.h

#pragma once
#include "ticketdecorator.h"

class Header2 :    public TicketDecorator
{
public:
    Header2(Component *myComponent);
    void prtTicket();
public:
    ~Header2(void);
};

Header2.cpp

#include "Header2.h"

Header2::Header2( Component *myComponent) : TicketDecorator( myComponent)
{
}

Header2::~Header2(void)
{
}

void Header2::prtTicket()
{
    // place printing header 2 code here
    callTrailer();
}

Footer1

TOP
Footer1.h

#pragma once
#include "ticketdecorator.h"

class Footer1 :    public TicketDecorator
{
public:
    Footer1(Component *myComponent);
    void prtTicket();
public:
    ~Footer1(void);
};

Footer1.cpp

#include "Footer1.h"

Footer1::Footer1(Component *myComponent) : TicketDecorator( myComponent)
{
}

Footer1::~Footer1(void)
{
}

void Footer1::prtTicket()
{
    callTrailer();
    // place printing footer 1 code here
}

Footer2

TOP
Footer2.h

#pragma once
#include "ticketdecorator.h"

class Footer2 :    public TicketDecorator
{
public:
    Footer2(Component *myComponent);
    void prtTicket();
public:
    ~Footer2(void);
};

Footer2.cpp

#include "Footer2.h"

Footer2::Footer2(Component *myComponent) : TicketDecorator( myComponent)
{
}

Footer2::~Footer2(void)
{
}

void Footer2::prtTicket()
{
    callTrailer();
    // place printing footer 2 code here
}