// Purpose.  Command                    class Deadbeat {
//                                      public:
// Discussion.  On the left, an IOU        Deadbeat( int v ) { cash_ = v; }
// has been encapsulated as a struct,      int payUp( int v ) {
// and TheBoss class is tightly coup-         cash_ -= v;  return v; }
// led to that struct.  On the right,      int rptCash() { return cash_; }
// TheBoss is only coupled to the ab-   private:
// stract class Command.  Lots of pos-     int cash_;
// sible derived classes could be sub-  };
// stituted: IOUs that call payUp() on
// Deadbeats, Checks that call cash()   class Command { public:
// on Banks, Stocks that call redeem()     virtual int execute() = 0;
// on Companies.  Each "command" is a   };
// "token" that gets transfered from
// one holder to another, until some-   class IOU : public Command {
// one chooses to "execute" it.         public:
                                           typedef int (Deadbeat::*Meth)(int);
class Deadbeat { public:                   IOU( Deadbeat* r, Meth a, int m ) {
   Deadbeat( int v ) { cash_ = v; }           obj_ = r;
   int payUp( int v ) {                       mth_ = a;
      cash_ -= v;  return v; }                amt_ = m; }
   int rptCash() { return cash_; }         int execute() {
private:                                      return (obj_->*mth_)( amt_ ); }
   int cash_;                           private:
};                                         Deadbeat*  obj_;
                                           Meth       mth_;
struct IOU {                               int        amt_;
   Deadbeat*  objPtr;                   };
   int (Deadbeat::*funPtr)( int );
   int        amt;                      class Enforcer {
};                                      public:
                                           Enforcer( Command& c ) : cmd_(c) {}
class Enforcer { public:                   Command& collect() { return cmd_; }
   Enforcer( IOU& m ) : mkr_(m) { }     private:
   IOU& collect() { return mkr_; }         Command& cmd_;
private:                                };
   IOU& mkr_;
};                                      class TheBoss {
                                        public:
class TheBoss {                            TheBoss() { cash_ = 1000; }
public:                                    collect( Command& cmd ) {
   TheBoss() { cash_ = 1000; }                cash_ += cmd.execute(); }
   collect( IOU& i ) {                     int rptCash() { return cash_; }
      cash_ +=                          private:
         ((i.objPtr)->*i.funPtr)(i.amt)    int cash_;
   }                                    };
   int rptCash() { return cash_; }
private:                                void main( void )
   int cash_;                           {
};                                         Deadbeat joe(90), tom(90);
                                           IOU one(&joe, &Deadbeat::payUp, 60);
void main( void )                          IOU two(&tom, &Deadbeat::payUp, 70);
{                                          Enforcer quido(one), lucca(two);
   Deadbeat joe(90), tom(90);              TheBoss  don;
   IOU one ={&joe, &Deadbeat::payUp,60}
   IOU two ={&tom, &Deadbeat::payUp,70}    don.collect( quido.collect() );
   Enforcer quido(one), lucca(two);        don.collect( lucca.collect() );
   TheBoss  don;                           cout << "joe has $" << joe.rptCash()
                                           cout << "tom has $" << tom.rptCash()
   don.collect( quido.collect() );         cout << "don has $" << don.rptCash()
   don.collect( lucca.collect() );      }
   cout << "joe has $" << joe.rptCash()
   cout << "tom has $" << tom.rptCash() // joe has $30
   cout << "don has $" << don.rptCash() // tom has $20
}                                       // don has $1130




// Purpose.  Command design pattern

// 1. Create a class that encapsulates some number of the following:
//       a "receiver" object
//       the method to invoke
//       the arguments to pass
// 2. Instantiate an object for each "callback"
// 3. Pass each object to its future "sender"
// 4. When the sender is ready to callback to the receiver, it calls execute()

#include <iostream>  #include <string>  using namespace std;
class Person;

class Command {                // 1. Create a class that encapsulates an object
   Person*  object;            //    and a member function
   void (Person::*method)();   // a pointer to a member function (the attri-
public:                        //    bute's name is "method")
   Command( Person* obj = 0, void (Person::*meth)() = 0 ) {
      object = obj;            // the argument's name is "meth"
      method = meth;
   }
   void execute() {
      (object->*method)();     // invoke the method on the object
}  };

class Person {
   string   name;
   Command  cmd;               // cmd is a "black box", it is a method invoca-
public:                        //    tion promoted to "full object status"
   Person( string n, Command c ) : cmd( c ) {
      name = n;
   }
   void talk() {               // "this" is the sender, cmd has the receiver
      cout << name << " is talking" << endl;
      cmd.execute();           // ask the "black box" to callback the receiver
   }
   void passOn() {
      cout << name << " is passing on" << endl;
      cmd.execute();           // 4. When the sender is ready to callback to
   }                           //    the receiver, it calls execute()
   void gossip() {
      cout << name << " is gossiping" << endl;
      cmd.execute();
   }
   void listen() {
      cout << name << " is listening" << endl;
}  };

void main( void ) {
   // Fred will "execute" Barney which will result in a call to passOn()
   // Barney will "execute" Betty which will result in a call to gossip()
   // Betty will "execute" Wilma which will result in a call to listen()
   Person wilma(  "Wilma",  Command() );
   // 2. Instantiate an object for each "callback"
   // 3. Pass each object to its future "sender"
   Person betty(  "Betty",  Command( &wilma,  &Person::listen ) );
   Person barney( "Barney", Command( &betty,  &Person::gossip ) );
   Person fred(   "Fred",   Command( &barney, &Person::passOn ) );
   fred.talk();
}

// Fred is talking
// Barney is passing on
// Betty is gossiping
// Wilma is listening




// Purpose.  Simple and "macro" commands
//
// Discussion.  Encapsulate a request as an object.  SimpleCommand
// maintains a binding between a receiver object and an action stored as a
// pointer to a member function.  MacroCommand maintains a sequence of
// Commands.  No explicit receiver is required because the subcommands
// already define their receiver.  MacroCommand may contain MacroCommands.

#include <iostream>
#include <vector>
using namespace std;

class Number { public:
   void dubble( int& value ) { value *= 2; }
};

class Command { public: virtual void execute( int& ) = 0; };

class SimpleCommand : public Command {
   typedef void (Number::* Action)(int&);
   Number* receiver;
   Action  action;
public:
   SimpleCommand( Number* rec, Action act ) {
      receiver = rec;
      action = act;
   }
   /*virtual*/ void execute( int& num ) { (receiver->*action)( num ); }
};

class MacroCommand : public Command {
   vector<Command*> list;
public:
   void add( Command* cmd ) { list.push_back( cmd ); }
   /*virtual*/ void execute( int& num ) {
      for (int i=0; i < list.size(); i++)
         list[i]->execute( num );
}  };

void main( void ) {
   Number object;
   Command* commands[3];
   commands[0] = &SimpleCommand( &object, &Number::dubble );

   MacroCommand two;
   two.add( commands[0] );   two.add( commands[0] );
   commands[1] = &two;

   MacroCommand four;
   four.add( &two );   four.add( &two );
   commands[2] = &four;

   int num, index;
   while (true) {
      cout << "Enter number selection (0=2x 1=4x 2=16x): ";
      cin >> num >> index;
      commands[index]->execute( num );
      cout << "   " << num << '\n';
}  }

// Enter number selection (0=2x 1=4x 2=16x): 3 0
//    6
// Enter number selection (0=2x 1=4x 2=16x): 3 1
//    12
// Enter number selection (0=2x 1=4x 2=16x): 3 2
//    48
// Enter number selection (0=2x 1=4x 2=16x): 4 0
//    8
// Enter number selection (0=2x 1=4x 2=16x): 4 1
//    16
// Enter number selection (0=2x 1=4x 2=16x): 4 2
//    64




// Purpose.  Command design pattern and inheritance
//
// Discussion.  The Command pattern promotes a deferred method invocation to
// full object status.  Each Command object is a "black box" - it is opaque to
// its holder/user.  Here, a portfolio's heterogeneous collection of financial
// instruments is being treated homogeneously, because, they all inherit from
// a common base class, and, they all have a "convert to currency" method with
// a common signature.

#include <iostream>
using namespace std;

class Instrument { public: virtual ~Instrument() { } };

class IOU : public Instrument {
   int amount;
public:
   IOU( int in ) { amount = in; }
   int payUp() { return amount; }
};

class Check : public Instrument {
   int amount;
public:
   Check( int in ) { amount = in; }
   int cash() { return amount; }
};

class Stock : public Instrument {
   int amount;
public:
   Stock( int in ) { amount = in; }
   int redeem() { return amount; }
};

class Command {
public:
   typedef int (Instrument::*Action)();
   Command( Instrument* o, Action m ) {
      object = o;
      method = m;
   }
   int execute() { return (object->*method)(); }
private:
   Instrument* object;
   Action      method;
};

void main( void ) {
   Command* portfolio[] = {  // old C cast, or new RTTI is required
      &Command( &IOU(100),   (int(Instrument::*)())&IOU::payUp ),
      &Command( &Check(200), static_cast<int(Instrument::*)()>(&Check::cash) ),
      &Command( &Stock(300), static_cast<int(Instrument::*)()>(&Stock::redeem) ) };
   for (int netWorth=0, i=0; i < 3; i++)
      netWorth += portfolio[i]->execute();
   cout << "net worth is now " << netWorth << '\n';
}

// net worth is now 600




// Purpose.  Command design pattern and class template

#include <iostream>
#include <string>
using namespace std;

class A {
   int divisor;
public:
   A( int div ) { divisor = div; }
   int divide( int in ) { return in / divisor; }
   int modulus( int in ) { return in % divisor; }
};

class B {
   string str;
public:
   B( string s ) { str = s; }
   string prepend(  string in ) { return in + str; }
   string postpend( string in ) { return str + in; }
};

template <typename CLS, typename ARG>
class Command {
public:
   typedef ARG (CLS::*Action)( ARG );
   Command( CLS* o, Action m, ARG a ) {
      object = o;
      method = m;
      argument = a;
   }
   ARG execute() { return (object->*method)( argument ); }
private:
   CLS*   object;
   Action method;
   ARG    argument;
};

void main( void ) {
   Command<A,int>* list1[4] = {
      &Command<A,int>( &A(3), &A::divide,  16 ),
      &Command<A,int>( &A(3), &A::modulus, 16 ),
      &Command<A,int>( &A(4), &A::divide,  16 ),
      &Command<A,int>( &A(4), &A::modulus, 16 ) };
   for (int i=0; i < 4; i++)
      cout << "numbers are " << list1[i]->execute() << '\n';

   B obj("abc");
   Command<B,string>* list2[4] = {
      new Command<B,string>( &obj, &B::prepend,  "123" ),
      new Command<B,string>( &obj, &B::prepend,  "xyz" ),
      new Command<B,string>( &obj, &B::postpend, "123" ),
      new Command<B,string>( &obj, &B::postpend, "xyz" ) };
   for (i=0; i < 4; i++)
      cout << "strings are " << list2[i]->execute() << '\n';
}

// numbers are 5
// numbers are 1
// numbers are 4
// numbers are 0
// strings are 123abc
// strings are xyzabc
// strings are abc123
// strings are abcxyz




// Purpose.  Command/Adapter design pattern (External Polymorphism demo)

// 1. Specify the new desired interface
// 2. Design a "wrapper" class that can "impedance match" the old to the new
// 3. The client uses (is coupled to) the new interface
// 4. The wrapper/adapter "maps" to the legacy implementation

#include <iostream.h>

class ExecuteInterface { public:                  // 1. Specify the new i/f
   virtual ~ExecuteInterface() { }
   virtual void execute() = 0;
};

template <class TYPE>                             // 2. Design a "wrapper" or
class ExecuteAdapter : public ExecuteInterface {  //    "adapter" class
public:
   ExecuteAdapter( TYPE* o, void (TYPE::*m)() ) { object = o;  method =m; }
   ~ExecuteAdapter()                            { delete object; }
   // 4. The adapter/wrapper "maps" the new to the legacy implementation
   void execute()             /* the new */     { (object->*method)(); }
private:                            
   TYPE* object;                                  // ptr-to-object attribute
   void (TYPE::*method)();    /* the old */       // ptr-to-member-function
};                                                //   attribute

// The old: three totally incompatible classes    // no common base class,
class Fea { public:                               // no hope of polymorphism
   ~Fea()        { cout << "Fea::dtor" << endl; }
   void doThis() { cout << "Fea::doThis()" << endl; }
};

class Feye { public:
   ~Feye()       { cout << "Feye::dtor" << endl; }
   void doThat() { cout << "Feye::doThat()" << endl; }
};

class Pheau { public:
   ~Pheau()          { cout << "Pheau::dtor" << endl; }
   void doTheOther() { cout << "Pheau::doTheOther()" << endl; }
};

/* the new is returned */ ExecuteInterface** initialize() {
   ExecuteInterface** array = new ExecuteInterface*[3]; /* the old is below */
   array[0] = new ExecuteAdapter<Fea>(   new Fea(),     &Fea::doThis       );
   array[1] = new ExecuteAdapter<Feye>(  new Feye(),    &Feye::doThat      );
   array[2] = new ExecuteAdapter<Pheau>( new Pheau(),   &Pheau::doTheOther );
   return array;
}

void main( void ) {
   ExecuteInterface** objects = initialize();

   for (int i=0; i < 3; i++) objects[i]->execute();  // 3. Client uses the new
                                                     //    (polymporphism)
   for (i=0; i < 3; i++) delete objects[i];
   delete objects;
}

// Fea::doThis()
// Feye::doThat()
// Pheau::doTheOther()
// Fea::dtor
// Feye::dtor
// Pheau::dtor




// Purpose.  Command design pattern demo
//
// Discussion.  Encapsulate a request as an object.  SimpleCommand
// maintains a binding between a receiver object and an action stored as a
// pointer to a member function.  MacroCommand maintains a sequence of
// Commands.  No explicit receiver is required because the subcommands
// already define their receiver.  MacroCommand may contain MacroCommands.

#include <iostream.h>

class Number {
public:
      Number( int value ) { _value = _copy = value; }
      int  getValue()     { return _value; }
      void increment()    { _copy = _value++; }
      void decrement()    { _copy = _value--; }
      void restore()      { _value = _copy; }
      void dubble()       { _copy = _value;  _value = 2 * _value; }
      void half()         { _copy = _value;  _value = _value / 2; }
      void square()       { _copy = _value;  _value = _value * _value; }
private:
      int _value;
      int _copy;
};


class Command {
public:
      virtual void execute() = 0;
      virtual void add( Command* ) { }
protected:
      Command() { }
};

class SimpleCommand : public Command {
public:
      typedef void (Number::* Action)();
      SimpleCommand( Number* receiver, Action action ) {
            _receiver = receiver;
            _action = action; }
      virtual void execute() { (_receiver->*_action)(); }
protected:
    Number* _receiver;
      Action  _action;
};

class MacroCommand : public Command {
public:
      MacroCommand() { _numCommands = 0; }
      void add( Command* cmd ) { _list[_numCommands++] = cmd; }
      virtual void execute();
private:
      Command* _list[10];
      int      _numCommands;
};

void MacroCommand::execute() {
      for (int i=0; i < _numCommands; i++)
            _list[i]->execute();
}

void main() {
      int i;
      cout << "Integer: ";
      cin >> i;
      Number*   object = new Number(i);

      Command*  commands[9];
      commands[1] = new SimpleCommand( object, &Number::increment );
      commands[2] = new SimpleCommand( object, &Number::decrement );
      commands[3] = new SimpleCommand( object, &Number::dubble );
      commands[4] = new SimpleCommand( object, &Number::half );
      commands[5] = new SimpleCommand( object, &Number::square );
      commands[6] = new SimpleCommand( object, &Number::restore );
      commands[7] = new MacroCommand;
      commands[7]->add( commands[1] );
      commands[7]->add( commands[3] );
      commands[7]->add( commands[5] );
      commands[8] = new MacroCommand;
      commands[8]->add( commands[7] );
      commands[8]->add( commands[7] );

      cout << "Exit[0], ++[1], --[2], x2[3], Half[4], Square[5], "
            << "Undo[6], do3[7] do6[8]: ";
      cin >> i;

      while (i)
      {
            commands[i]->execute();
            cout << "   " << object->getValue() << endl;
            cout << "Exit[0], ++[1], --[2], x2[3], Half[4], Square[5], "
                  << "Undo[6], do3[7] do6[8]: ";
            cin >> i;
      }
}

// Integer: 4
// Exit[0], ++[1], --[2], x2[3], Half[4], Square[5], Undo[6], do3[7] do6[8]: 1
//    5
// Exit[0], ++[1], --[2], x2[3], Half[4], Square[5], Undo[6], do3[7] do6[8]: 3
//    10
// Exit[0], ++[1], --[2], x2[3], Half[4], Square[5], Undo[6], do3[7] do6[8]: 2
//    9
// Exit[0], ++[1], --[2], x2[3], Half[4], Square[5], Undo[6], do3[7] do6[8]: 4
//    4
// Exit[0], ++[1], --[2], x2[3], Half[4], Square[5], Undo[6], do3[7] do6[8]: 5
//    16
// Exit[0], ++[1], --[2], x2[3], Half[4], Square[5], Undo[6], do3[7] do6[8]: 6
//    4
// Exit[0], ++[1], --[2], x2[3], Half[4], Square[5], Undo[6], do3[7] do6[8]: 6
//    4
// Exit[0], ++[1], --[2], x2[3], Half[4], Square[5], Undo[6], do3[7] do6[8]: 7
//    100
// Exit[0], ++[1], --[2], x2[3], Half[4], Square[5], Undo[6], do3[7] do6[8]: 6
//    10
// Exit[0], ++[1], --[2], x2[3], Half[4], Square[5], Undo[6], do3[7] do6[8]: 8
//    940900