// Object-oriented Modeling and Design // Ticket Decorator #include using std::cout; using std::endl; /* Abstract component */ class Component { public: virtual void prtTicket() = 0; }; /* Concrete component */ class SalesTicket : public Component{ public: void prtTicket(){ // Base function cout << "TICKET" << endl; } }; /* Base of decorators */ class Decorator : public Component { public: Decorator(Component* myC) : myComp{myC} { // Constructor // Takes the address of the next component } void prtTicket(){ // Calls the next component if (myComp) myComp->prtTicket(); } private: Component *myComp; // Pointer to the next component }; class Header1 : public Decorator { // Header1 decorator public: Header1(Component *); void prtTicket(); }; Header1::Header1(Component* myC) :Decorator{ myC } {} void Header1::prtTicket(){ cout << "HEADER 1" << endl; // Header1’s specific function Decorator::prtTicket(); // Calls the method of the base class. } class Header2 : public Decorator { // Header2 decorator public: Header2(Component *); void prtTicket(); }; Header2::Header2(Component* myC) :Decorator{ myC } {} void Header2::prtTicket(){ cout << "HEADER 2" << endl; Decorator::prtTicket(); } class Footer1 : public Decorator { // Footer1 decorator public: Footer1(Component *); void prtTicket(); }; Footer1::Footer1(Component* myC) :Decorator{ myC } {} void Footer1::prtTicket(){ Decorator::prtTicket(); cout << "FOOTER 1" << endl; } class Footer_Picture : public Decorator { // Footer Picture decorator public: Footer_Picture(Component*); void prtTicket(); }; Footer_Picture::Footer_Picture(Component* myC) :Decorator{ myC } {} void Footer_Picture::prtTicket() { Decorator::prtTicket(); cout << "I print a picture" << endl; } /* A client class to test the system */ class SalesOrder { Component *myTicket; // Pointer to ticket component public: SalesOrder(Component* mT) :myTicket{ mT } {} void prtTicket(){ myTicket->prtTicket(); } }; /* The main function for testing */ int main() { /*Create the list (chain) of components*/ /*In a real system, this list can be created by a Factory object.*/ SalesTicket* st = new SalesTicket{}; Footer1* f1 = new Footer1{ st }; Footer_Picture* fp = new Footer_Picture{ f1 }; Header2* h2 = new Header2{ fp }; Header1* h1 = new Header1{ h2 }; /* The starting address (h1) is assigned to the SalesOrder*/ SalesOrder sale(h1); //In a real system this address can be received from a Factory object. sale.prtTicket(); delete st, f1, fp, h1, h2; return 0; }