The Trans.cpp File

 <  Free Open Study  >  

 // Trans.cpp: The source code for the Transaction classes. The  // Transaction classes are interesting since they appear on both // sides of the application. The Transaction objects on each side // of the application could be completely different definitions. // For convenience, they were made the same in this example. The // parts of the public interface unique to one side of the // application are restricted through the use of the BANK_SIDE or // ATM_SIDE macros. #define BANK_SIDE #ifdef ATM_SIDE #include ''atm.hpp'' #endif #ifdef BANK_SIDE #include ''bank.hpp'' #endif #include ''trans.hpp'' // The TimeStamp constructor uses the time and ctime standard C // library functions to create a simple string capturing data and // time. TimeStamp::TimeStamp() {      time_t timer;      time(&timer);      strcpy(date_time, ctime(&timer)); } void TimeStamp::print(FILE* fd) {      fprintf(fd, ''%s'', date_time); } Transaction::Transaction(char* account, char* p, double a) {      strcpy(source_account, account);      strcpy(pin, p);      amount = a; } // These are protected accessor methods for use by the four derived // classes of the Transaction class. char* Transaction::get_source_account() {      return(source_account); } double Transaction::get_amount() {      return(amount); } void Transaction::set_amount(double new_amount) {    amount = new_amount; } void Transaction::print(FILE* fd) {      timeStamp.print(fd);      fprintf(fd, ''\tAccount:%s\tAmount:%4.21f\n'',       source_account,        amount); } #ifdef ATM_SIDE // If the application is the ATM side, then define the preprocess, // postprocess, and update methods to do nothing. The packetize // method is responsible for building a string, which consists of a // type field (four characters), the source account (seven // characters), a space, a PIN number (four characters), a space, // an amount (nine characters), a space, and a NULL terminator. // This string is suitable for shipping across a network, or it can // be transformed into something that can be shipped across a // network. int Transaction::preprocess(ATM*) {      return(0); } void Transaction::postprocess(ATM*) { } void Transaction::update(char* info, int count) { } void Transaction::packetize(char* buf) {    char type_buf[small_string];    strcpy(type_buf, type());    type_buf[4]=' 
 // Trans.cpp: The source code for the Transaction classes. The // Transaction classes are interesting since they appear on both // sides of the application. The Transaction objects on each side // of the application could be completely different definitions. // For convenience, they were made the same in this example. The // parts of the public interface unique to one side of the // application are restricted through the use of the BANK_SIDE or // ATM_SIDE macros. #define BANK_SIDE #ifdef ATM_SIDE #include ''atm.hpp'' #endif #ifdef BANK_SIDE #include ''bank.hpp'' #endif #include ''trans.hpp'' // The TimeStamp constructor uses the time and ctime standard C // library functions to create a simple string capturing data and // time. TimeStamp::TimeStamp() { time_t timer; time(&timer); strcpy(date_time, ctime (&timer)); } void TimeStamp::print(FILE* fd) { fprintf(fd, ''%s'', date_time); } Transaction::Transaction(char* account, char* p, double a) { strcpy(source_account, account); strcpy(pin, p); amount = a; } // These are protected accessor methods for use by the four derived // classes of the Transaction class. char* Transaction::get_source_account() { return(source_account); } double Transaction::get_amount() { return(amount); } void Transaction::set_amount(double new_amount) { amount = new_amount; } void Transaction::print(FILE* fd) { timeStamp.print(fd); fprintf(fd, ''\tAccount:%s\tAmount:%4.21f\n'', source_account, amount); } #ifdef ATM_SIDE // If the application is the ATM side, then define the preprocess, // postprocess, and update methods to do nothing. The packetize // method is responsible for building a string, which consists of a // type field (four characters), the source account (seven // characters), a space, a PIN number (four characters), a space, // an amount (nine characters ), a space, and a NULL terminator. // This string is suitable for shipping across a network, or it can // be transformed into something that can be shipped across a // network. int Transaction::preprocess(ATM*) { return(0); } void Transaction::postprocess(ATM*) { } void Transaction::update(char* info , int count) { } void Transaction::packetize(char* buf) { char type_buf[small_string]; strcpy (type_buf, type()); type_buf[4]='\0'; sprintf(buf, ''%s%s %s %4.21f'', type_buf, source_account, pin, amount); } #endif // If this is the Bank side of the application, include a // verify_account method, which checks if an account's name and // PIN match that of the Transaction. #ifdef BANK_SIDE int Transaction::verify_account(Account* a) { return(a->verify_account(source_account, pin)); } void Transaction::packetize(int status, char* buf) { sprintf(buf, ''%4d %4.21f'', status, amount); cout << ''Bank packetized network object: \'' '' << buf << ''\''\n''; } #endif Deposit::Deposit(char* account, char* p, double a) : Transaction(account, p, a) { } void Deposit::print(FILE* fd) { fprintf(fd, ''Deposit: ''); Transaction::print(fd); } char* Deposit::type() { return(''Deposit''); } // Preprocessing deposits requires grabbing an envelope. Nothing // can go wrong with this in the simulation, but in the world of // hardware we would have to consider timeouts, jammed envelopes, // etc. In the real world, the DepositSlot::retrieve_envelope // method would be implemented to handle these cases. #ifdef ATM_SIDE int Deposit::preprocess(ATM* a) { return(a->retrieve_envelope()); } #endif // Processing a Deposit transaction involves getting the source // account, verifying it, and then modifying the balance to reflect // the deposited amount. This is a bit of a simplification from the // real world, where a ''shadow'' account might be updated but a // human needs to retrieve the envelope and check to be sure that // money was actually included. This method suits our purposes, // which is to show the design and implementation of a distributed // process. #ifdef BANK_SIDE int Deposit::process(AccountList* accounts) { Account* account = accounts->find_account(get_source_account()); if (account == NULL) { return(1); } if (!Transaction::verify_account(account)) { return(1); } account->modify_balance(get_amount()); return(0); } #endif Withdraw::Withdraw(char* account, char* p, double a) : Transaction(account, p, a) { } void Withdraw::print(FILE* fd) { fprintf(fd, ''Withdraw: ''); Transaction::print(fd); } char* Withdraw::type() { return(''Withdraw''); } // Preprocessing a withdrawal involves checking the cash // dispenser to be sure the ATM has enough cash. Postprocessing // gives the user the cash. #ifdef ATM_SIDE int Withdraw::preprocess(ATM* a) { return(!a->enough_cash(get_amount())); } void Withdraw::postprocess(ATM* a) { a->dispense_cash(get_amount()); } #endif // The processing of a Withdraw transaction requires finding the // source account, verifying the account, ensuring there is enough // cash in the account, and, only then, reducing the amount of money // in the account. #ifdef BANK_SIDE int Withdraw::process(AccountList* accounts) { Account* account = accounts->find_account(get_source_account()); if (account == NULL   !account->check_balance (get_amount())) { return(1); } if (! Transaction::verify_account(account)) { return(1); } account->modify_balance(-get_amount()); return(0); } #endif Balance::Balance(char* account, char* p) : Transaction(account, p, 0.0) { } void Balance::print(FILE* fd) { fprintf(fd, ''Balance: ''); Transaction::print(fd); } char* Balance::type() { return(''Balance''); } // Processing a Balance involves finding the source account and // copying its balance into the Amount field of the Transaction // object. This assumes the account name and PIN were verified . #ifdef BANK_SIDE int Balance::process(AccountList* accounts) { Account* account = accounts->find_account(get_source_account()); if (account == NULL) { return(1); } if (!Transaction::verify_account(account)) { return(1); } set_amount(account->get_balance()); return(0); } #endif // The update method for Balance (on the ATM side of the // application) is used to copy the retrieved balance back into the // corresponding Transaction object on the ATM side. #ifdef ATM_SIDE void Balance::update(char* info, int count) { set_amount(atof(info)); } #endif Transfer::Transfer(char* s_account, char* p, char* t_account, double a) : Transaction(s_account, p, a) { strcpy(target_account, t_account); } void Transfer::print(FILE* fd) { fprintf(fd, ''Transfer: ''); Transaction::print(fd); fprintf(fd, ''\tTarget Account: %s\n\n'', target_ account); } char* Transfer::type() { return(''Transfer''); } // Packetizing a transfer implies including the target account at // the end of the packet. #ifdef ATM_SIDE void Transfer::packetize(char* buf) { Transaction::packetize(buf); strcat(buf, '' ''); strcat(buf, target_account); } #endif // Processing a Transfer object requires that we retrieve the // source and target accounts, verify the source account, ensure // that the source account has enough money for the transfer, and // only then update the balances of the source (by subtracting the // amount) and the target (by adding the equivalent amount). #ifdef BANK_SIDE int Transfer::process(AccountList* accounts) { Account* src_account = accounts->find_account (get_source_account()); Account* tar_account = accounts->find_account(target_account); if (src_account == NULL  tar_account == NULL) { return(1); } if (!Transaction::verify_account(src_account)) { return(1); } if (!src_account->check_balance(get_amount())) { return(1); } src_account->modify_balance(-get_amount()); tar_account->modify_balance(get_amount()); return(0); } #endif TransactionList::TransactionList(unsigned sz) { transnum = 0; TransList = new Transaction*[size=sz]; } TransactionList::~TransactionList() { cleanup(); delete TransList; } int TransactionList::add_trans(Transaction* t) { if (transnum < size ) { TransList[transnum++] = t; return(0); } return(1); } void TransactionList::cleanup() { int i; for (i=0; i < transnum; i++) { delete TransList[i]; } } void TransactionList:sprint(FILE* fd) { int i; for (i=0; i < transnum; i++) { TransList[i]->print{fd); } } 
'; sprintf(buf, ''%s%s %s %4.21f'', type_buf, source_account, pin, amount); } #endif // If this is the Bank side of the application, include a // verify_account method, which checks if an account's name and // PIN match that of the Transaction. #ifdef BANK_SIDE int Transaction::verify_account(Account* a) { return(a->verify_account(source_account, pin)); } void Transaction::packetize(int status, char* buf) { sprintf(buf, ''%4d %4.21f'', status, amount); cout << ''Bank packetized network object: \'' '' << buf << ''\''\n''; } #endif Deposit::Deposit(char* account, char* p, double a) : Transaction(account, p, a) { } void Deposit::print(FILE* fd) { fprintf(fd, ''Deposit: ''); Transaction::print(fd); } char* Deposit::type() { return(''Deposit''); } // Preprocessing deposits requires grabbing an envelope. Nothing // can go wrong with this in the simulation, but in the world of // hardware we would have to consider timeouts, jammed envelopes, // etc. In the real world, the DepositSlot::retrieve_envelope // method would be implemented to handle these cases. #ifdef ATM_SIDE int Deposit::preprocess(ATM* a) { return(a->retrieve_envelope()); } #endif // Processing a Deposit transaction involves getting the source // account, verifying it, and then modifying the balance to reflect // the deposited amount. This is a bit of a simplification from the // real world, where a ''shadow'' account might be updated but a // human needs to retrieve the envelope and check to be sure that // money was actually included. This method suits our purposes, // which is to show the design and implementation of a distributed // process. #ifdef BANK_SIDE int Deposit::process(AccountList* accounts) { Account* account = accounts->find_account(get_source_account()); if (account == NULL) { return(1); } if (!Transaction::verify_account(account)) { return(1); } account->modify_balance(get_amount()); return(0); } #endif Withdraw::Withdraw(char* account, char* p, double a) : Transaction(account, p, a) { } void Withdraw::print(FILE* fd) { fprintf(fd, ''Withdraw: ''); Transaction::print(fd); } char* Withdraw::type() { return(''Withdraw''); } // Preprocessing a withdrawal involves checking the cash // dispenser to be sure the ATM has enough cash. Postprocessing // gives the user the cash. #ifdef ATM_SIDE int Withdraw::preprocess(ATM* a) { return(!a->enough_cash(get_amount())); } void Withdraw::postprocess(ATM* a) { a->dispense_cash(get_amount()); } #endif // The processing of a Withdraw transaction requires finding the // source account, verifying the account, ensuring there is enough // cash in the account, and, only then, reducing the amount of money // in the account. #ifdef BANK_SIDE int Withdraw::process(AccountList* accounts) { Account* account = accounts->find_account(get_source_account()); if (account == NULL !account->check_balance (get_amount())) { return(1); } if (! Transaction::verify_account(account)) { return(1); } account->modify_balance(-get_amount()); return(0); } #endif Balance::Balance(char* account, char* p) : Transaction(account, p, 0.0) { } void Balance::print(FILE* fd) { fprintf(fd, ''Balance: ''); Transaction::print(fd); } char* Balance::type() { return(''Balance''); } // Processing a Balance involves finding the source account and // copying its balance into the Amount field of the Transaction // object. This assumes the account name and PIN were verified. #ifdef BANK_SIDE int Balance::process(AccountList* accounts) { Account* account = accounts->find_account(get_source_account()); if (account == NULL) { return(1); } if (!Transaction::verify_account(account)) { return(1); } set_amount(account->get_balance()); return(0); } #endif // The update method for Balance (on the ATM side of the // application) is used to copy the retrieved balance back into the // corresponding Transaction object on the ATM side. #ifdef ATM_SIDE void Balance::update(char* info, int count) { set_amount(atof(info)); } #endif Transfer::Transfer(char* s_account, char* p, char* t_account, double a) : Transaction(s_account, p, a) { strcpy(target_account, t_account); } void Transfer::print(FILE* fd) { fprintf(fd, ''Transfer: ''); Transaction::print(fd); fprintf(fd, ''\tTarget Account: %s\n\n'', target_ account); } char* Transfer::type() { return(''Transfer''); } // Packetizing a transfer implies including the target account at // the end of the packet. #ifdef ATM_SIDE void Transfer::packetize(char* buf) { Transaction::packetize(buf); strcat(buf, '' ''); strcat(buf, target_account); } #endif // Processing a Transfer object requires that we retrieve the // source and target accounts, verify the source account, ensure // that the source account has enough money for the transfer, and // only then update the balances of the source (by subtracting the // amount) and the target (by adding the equivalent amount). #ifdef BANK_SIDE int Transfer::process(AccountList* accounts) { Account* src_account = accounts->find_account (get_source_account()); Account* tar_account = accounts->find_account(target_account); if (src_account == NULL tar_account == NULL) { return(1); } if (!Transaction::verify_account(src_account)) { return(1); } if (!src_account->check_balance(get_amount())) { return(1); } src_account->modify_balance(-get_amount()); tar_account->modify_balance(get_amount()); return(0); } #endif TransactionList::TransactionList(unsigned sz) { transnum = 0; TransList = new Transaction*[size=sz]; } TransactionList::~TransactionList() { cleanup(); delete TransList; } int TransactionList::add_trans(Transaction* t) { if (transnum < size) { TransList[transnum++] = t; return(0); } return(1); } void TransactionList::cleanup() { int i; for (i=0; i < transnum; i++) { delete TransList[i]; } } void TransactionList:sprint(FILE* fd) { int i; for (i=0; i < transnum; i++) { TransList[i]->print{fd); } }
 <  Free Open Study  >  


Object-Oriented Design Heuristics
Object-Oriented Design Heuristics (paperback)
ISBN: 0321774965
EAN: 2147483647
Year: 1996
Pages: 180

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net