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: $ */