// Purpose.  Facade                     #include <iostream.h>
//                                      #include <string.h>
// Discussion.  Class Compute models    #define sl strlen
// a decimal digit adder module.  An
// entire "subsystem" can be configur-  class Compute {
// ed by linking as many of these       public:
// modules as the desired precision        char add( char a, char b, int& c ) {
// requires.  The "subsystem" being           int result = a + b + c - 96;
// modeled in main() is complex and           c = 0;
// burdensome to use.  Wrapping this          if (result > 9) {
// subsystem inside of a Facade that             result -= 10;
// exports a simple interface is                 c = 1;
// desirable.                                 }
                                              return result + 48;
#include <iostream.h>                      }
#include <string.h>                     };
#define sl strlen
                                        class Facade {
class Compute {                         public:
public:                                 char* add( char* a, char* b ) {
   char add( char a, char b, int& c) {     int cary = 0, i = 0;
      int result = a + b + c - 96;         char c, d;
      c = 0;                               if ((sl(a) > 1) && (sl(b) > 1)) {
      if (result > 9) {                       c = ones.add( a[1], b[1], cary );
         result -= 10;                        d = tens.add( a[0], b[0], cary );
         c = 1;                            } else if (sl(a) > 1) {
      }                                       c = ones.add( a[1], b[0], cary );
      return result + 48;                     d = tens.add( a[0],  '0', cary );
   }                                       } else if (sl(b) > 1) {
};                                            c = ones.add( b[1], a[0], cary );
                                              d = tens.add( b[0],  '0', cary );
void main( void ) {                        } else {
   Compute  tens, ones;                       c = tens.add( a[0], b[0], cary );
   char     a[9], b[9], c, d;                 d = 'x';
   int      cary;                          }
while (1) {                                if (cary) ans[i++] = '1';
   cout << "Enter 2 nums: ";               if (d != 'x') ans[i++] =  d;
   cin >> a >> b;                          ans[i++] = c;
   cout << "   sum is ";                   ans[i] = '\0';
   cary = 0;                               return ans;
   if ((sl(a) > 1) && (sl(b) > 1)) {    }
      c = ones.add( a[1], b[1], cary);  private:
      d = tens.add( a[0], b[0], cary);     Compute  tens, ones;
   } else if (sl(a) > 1) {                 char     ans[9];
      c = ones.add( a[1], b[0], cary);  };
      d = tens.add( a[0],  '0', cary);
   } else if (sl(b) > 1) {              void main( void ) {
      c = ones.add( b[1], a[0], cary);     Facade  f;
      d = tens.add( b[0],  '0', cary);     char    a[9], b[9];
   } else {                                while (1) {
      c = tens.add( a[0], b[0], cary);        cout << "Enter 2 nums: ";
      d = 'x';                                cin >> a >> b;
   }                                          cout <<"   sum is "<< f.add(a,b)
   if (cary) cout << '1';                        << endl;
   if (d != 'x') cout << d;             }  }
   cout << c << endl;
}  }                                    // Enter 2 nums: 9 13
                                        //    sum is 22
// Enter 2 nums: 99 99                  // Enter 2 nums: 19 8
//    sum is 198                        //    sum is 27
// Enter 2 nums: 38 83                  // Enter 2 nums: 3 99
//    sum is 121                        //    sum is 102
// Enter 2 nums: 5 6
//    sum is 11



// Purpose.  Facade design pattern demo.
//
// Discussion.  Structuring a system into subsystems helps reduce
// complexity.  A common design goal is to minimize the communication and
// dependencies between subsystems.  One way to achieve this goal is to
// introduce a "facade" object that provides a single, simplified
// interface to the many, potentially complex, individual interfaces
// within the subsystem.  In this example, the "subsystem" for responding
// to a networking service request has been modeled, and a facade
// (FacilitiesFacade) interposed.  The facade "hides" the twisted and
// bizarre choreography necessary to satisfy even the most basic of
// requests.  All the user of the facade object has to do is make one or
// two phone calls a week for 5 months, and a completed service request
// results.

#include <iostream.h>

class MisDepartment {
public:
      void submitNetworkRequest() { _state = 0; }
      bool checkOnStatus() {
            _state++;
            if (_state == Complete)
                  return 1;
            return 0; }
private:
      enum States {Received, DenyAllKnowledge, ReferClientToFacilities,
            FacilitiesHasNotSentPaperwork, ElectricianIsNotDone,
            ElectricianDidItWrong, DispatchTechnician, SignedOff, DoesNotWork,
            FixElectriciansWiring, Complete};
      int _state;
};

class ElectricianUnion {
public:
      void submitNetworkRequest() { _state = 0; }
      bool checkOnStatus() {
            _state++;
            if (_state == Complete)
                  return 1;
            return 0; }
private:
      enum States {Received, RejectTheForm, SizeTheJob, SmokeAndJokeBreak,
            WaitForAuthorization, DoTheWrongJob, BlameTheEngineer, WaitToPunchOut,
            DoHalfAJob, ComplainToEngineer, GetClarification, CompleteTheJob,
            TurnInThePaperwork, Complete};
      int _state;
};

class FacilitiesDepartment {
public:
      void submitNetworkRequest() { _state = 0; }
      bool checkOnStatus() {
            _state++;
            if (_state == Complete)
                  return 1;
            return 0; }
private:
      enum States {Received, AssignToEngineer, EngineerResearches,
            RequestIsNotPossible, EngineerLeavesCompany, AssignToNewEngineer,
            NewEngineerResearches, ReassignEngineer, EngineerReturns,
            EngineerResearchesAgain, EngineerFillsOutPaperWork, Complete};
      int _state;
};

class FacilitiesFacade {
public:
      FacilitiesFacade()          { _count = 0; }
      void submitNetworkRequest() { _state = 0; }
      bool checkOnStatus() {
            _count++;
            /* Job request has just been received */
            if (_state == Received) {
                  _state++;
                  /* Forward the job request to the engineer */
                  _engineer.submitNetworkRequest();
                  cout << "submitted to Facilities - " << _count
                        << " phone calls so far" << endl; }
            else if (_state == SubmitToEngineer) {
                  /* If engineer is complete, forward to electrician */
                  if (_engineer.checkOnStatus()) {
                        _state++;
                        _electrician.submitNetworkRequest();
                        cout << "submitted to Electrician - " << _count
                              << " phone calls so far" << endl; } }
            else if (_state == SubmitToElectrician) {
                  /* If electrician is complete, forward to technician */
                  if (_electrician.checkOnStatus()) {
                        _state++;
                        _technician.submitNetworkRequest();
                        cout << "submitted to MIS - " << _count
                              << " phone calls so far" << endl; } }
            else if (_state == SubmitToTechnician) {
                  /* If technician is complete, job is done */
                  if (_technician.checkOnStatus())
                        return 1; }
            /* The job is not entirely complete */
            return 0; }
      int getNumberOfCalls() { return _count; }
private:
      enum States {Received, SubmitToEngineer, SubmitToElectrician,
            SubmitToTechnician};
      int                   _state;
      int                   _count;
      FacilitiesDepartment  _engineer;
      ElectricianUnion      _electrician;
      MisDepartment         _technician;
};

void main() {
      FacilitiesFacade  facilities;

      facilities.submitNetworkRequest();
      /* Keep checking until job is complete */
      while ( ! facilities.checkOnStatus())
            ;
      cout << "job completed after only " << facilities.getNumberOfCalls()
            << " phone calls" << endl;
}

// submitted to Facilities - 1 phone calls so far
// submitted to Electrician - 12 phone calls so far
// submitted to MIS - 25 phone calls so far
// job completed after only 35 phone calls