Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Examples  

examp12.cpp

This example is to show use of the Proxy pattern.

Our focus is on the use of restrictive access to accessors and mutators.

Contributors

AbstractBankAccount - which has the usual interface for fund management.

BankAccount - Concrete implementation of above

AccountProxy - Non-restrictive proxy which derives from subject

RestrictedAccountProxy - subclass of AccountProxy which restricts access to deposits and displays only.

Notes:

By deriving the base AccountProxy from AbstractBankAccount, the proxy can be used as the latter (as in our example). But this is not required, if you want your application to expose the proxy types then you wouldn't need to derive from the domain types. This may prove more flexible in a complex class model.

/*
  CoreLinux++ 
  Copyright (C) 2000 CoreLinux Consortium
  
   The CoreLinux++ Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The CoreLinux++ Library Library is distributed in the hope that it will 
   be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  
*/   

#include <Common.hpp>
#include <BankAccount.hpp>
#include <AccountProxy.hpp>
#include <RestrictedAccountProxy.hpp>

using namespace corelinux;

#include <iostream>
#include <exception>

//
// Otherstuff
//


//
// In module function prototypes
//

int   main( void );

void  doWork( void );
void  addFunds( AbstractBankAccountPtr );
void  removeFunds( AbstractBankAccountPtr );
void  showBalance( AbstractBankAccountPtr );

//
// Functions that work with Engine types
//

void  handleAssertion( AssertionCref );
void  handleException( ExceptionCref );

int main( void )
{

   //
   // Practice gracefull exception management
   //

   cout << endl;

   try
   {
      doWork();
   }

   catch( AssertionRef aAssert )
   {
      handleAssertion(aAssert);
   }
   catch( ExceptionRef aException )
   {
      handleException(aException);
   }
   catch( std::exception & e )
   {
      cerr  << e.what() << endl;
   }
   catch( ... )
   {
      cerr  << "Unknown exception." << endl;
   }

   return 0;               
}

void  displayMenu( void )
{
   cout  << endl;
   cout  << "\tDeposit Funds     1" << endl;
   cout  << "\tWithdraw Funds    2" << endl;
   cout  << "\tDisplay Balance   3" << endl;
   cout  << "\tToggle Access     4" << endl;
   cout  << "\tQuit              5" << endl;
   cout  << endl;
}

Int   getCommand( void )
{
   displayMenu();

   Int   aOption;

   cout  << "Enter the option number on the right to execute : ";
   cin   >> aOption;
   cout  << endl;

   return aOption;
}

const Amount   startingBalance(20.0);

void  doWork( void  )
{
   bool  keepWorking(true);

   //
   // Open an account with 20.00 dollars, assume full
   // access and manage funds
   //

   BankAccount             anAccount(startingBalance);
   AccountProxy            aProxy(&anAccount);
   RestrictedAccountProxy  aRProxy(&anAccount);
   AbstractBankAccountPtr  currentAccount(&aProxy);

   cout << "Account started with a fist full of dollars." << endl;
   do
   {
      Int   aCommand( getCommand() );

      if( aCommand > 5 || aCommand < 0 )
      {
         cerr << "You can't enter non-numeric options!" << endl;
         aCommand = 5;
      }
      else
      {
         ;  // do nothing
      }

      switch( aCommand )
      {
         //
         // Deposit funds
         //

         case  1:
            {
               addFunds( currentAccount );
               break;
            }

         //
         // Withdraw funds
         //

         case  2:
            {
               removeFunds( currentAccount );
               break;
            }

         //
         // Display balance
         //

         case  3:
            {
               showBalance( currentAccount );
               break;
            }

         //
         // Change access
         //

         case  4:
            {
               if( currentAccount == &aProxy )
               {
                  cout  << "Account now restricted." << endl;
                  currentAccount = &aRProxy;
               }
               else
               {
                  cout  << "Account restrictions disabled." << endl;
                  currentAccount = &aProxy;
               }
               break;
            }

         //
         // Exit routine
         //

         case  5:
            keepWorking=false;
            break;

         default:
            ;  //do nothing
            break;
      }
   } while( keepWorking == true );

}

//
// Deposit funds from the account
//

void  addFunds( AbstractBankAccountPtr aAccount )
{
   Amount   total(0.0);
   cout  << "Enter the amount of funds to deposit : ";
   cin   >> total;
   try
   {
      aAccount->depositFunds( total );
   }
   catch( InsufficientFundsExceptionRef aExcp )
   {
      cerr << aExcp.getWhy() << endl;
   }

   return;
}

//
// Withdraw funds from the account
//

void  removeFunds( AbstractBankAccountPtr aAccount )
{
   Amount   total(0.0);
   cout  << "Enter the amount of funds to withdraw : ";
   cin   >> total;
   try
   {
      aAccount->withdrawFunds( total );
   }
   catch( InsufficientFundsExceptionRef aExcp )
   {
      cerr << aExcp.getWhy() << endl;
   }

   return;
}

//
// Show the balance and please excuse the lack of
// locale sensitivity
//

void  showBalance( AbstractBankAccountPtr aAccount )
{
   cout  << "The total account balance : $ " << 
      aAccount->getBalance() << endl;

   return;
}

//
// Peform default (just show it)
//

void  handleAssertion( AssertionCref aAssert )
{
   cerr << aAssert.getFile() << ":" << aAssert.getLine() << ":" << 
      "Assertion: ";

   if( aAssert.getType() == Assertion::NEVERGETHERE )
   {
      cerr << "NEVER_GET_HERE";
   }
   else
   {
      if( aAssert.getType() == Assertion::REQUIRE )
      {
         cerr  << "REQUIRE";
      }
      else if( aAssert.getType() == Assertion::ENSURE )
      {
         cerr  << "ENSURE";
      }
      else if( aAssert.getType() == Assertion::CHECK )
      {
         cerr  << "CHECK";
      }
      else 
      {
         cerr  << "ASSERT";
      }
      cerr << "( " << aAssert.getWhy() << " )";
   }

   cerr << endl;
}

void  handleException( ExceptionCref aExcp )
{
   cerr << aExcp.getFile() << ":" << aExcp.getLine() << ":" <<
      "Exception: " << aExcp.getWhy() << endl;
}

/*
   Common rcs information do not modify
   $Author: prudhomm $
   $Revision: 1.2 $
   $Date: 2000/08/31 22:50:31 $
   $Locker:  $
*/



This is the CoreLinux++ reference manual
Provided by The CoreLinux Consortium